1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "../port/error.h"
7 #include "ureg.h"
8
9 extern int (*breakhandler)(Ureg *ur, Proc*); /* trap.c */
10 extern Instr BREAK; /* trap.c */
11 extern void portbreakinit(void);
12
13 #define getop(i) ((i>>26)&0x3F)
14 #define getxo(i) ((i>>1)&0x3FF)
15 #define getbobi(i) bo = (i>>21)&0x1f; bi = (i>>16)&0x1f; xx = (i>>11)&0x1f;
16
17 void
machbreakinit(void)18 machbreakinit(void)
19 {
20 portbreakinit();
21 breakhandler = breakhit;
22 }
23
24 Instr
machinstr(ulong addr)25 machinstr(ulong addr)
26 {
27 if (addr < KTZERO)
28 error(Ebadarg);
29 return *(Instr*)addr;
30 }
31
32 void
machbreakset(ulong addr)33 machbreakset(ulong addr)
34 {
35 if (addr < KTZERO)
36 error(Ebadarg);
37 *(Instr*)addr = BREAK;
38 segflush((void*)addr, sizeof(Instr));
39 }
40
41 void
machbreakclear(ulong addr,Instr i)42 machbreakclear(ulong addr, Instr i)
43 {
44 if (addr < KTZERO)
45 error(Ebadarg);
46 *(Instr*)addr = i;
47 segflush((void*)addr, sizeof(Instr));
48 }
49
50 static int
condok(Ureg * ur,ulong ir,int ctrok)51 condok(Ureg *ur, ulong ir, int ctrok)
52 {
53 int bo, bi, xx;
54 ulong ctrval;
55
56 ctrval = ur->ctr;
57 getbobi(ir);
58 if(xx)
59 return 0; /* illegal */
60 if((bo & 0x4) == 0) {
61 if(!ctrok)
62 return 0; /* illegal */
63 ctrval--;
64 }
65 if(bo & 0x4 || (ctrval!=0)^((bo>>1)&1)) {
66 if(bo & 0x10 || (((ur->cr & (1L<<(31-bi))!=0)==((bo>>3)&1))))
67 return 1;
68 }
69 return 0;
70 }
71
72 /*
73 * Return the address of the instruction that will be executed after the
74 * instruction at ur->pc, accounting for current branch conditions.
75 */
76 ulong
machnextaddr(Ureg * ur)77 machnextaddr(Ureg *ur)
78 {
79 long imm;
80 ulong ir;
81
82 ir = *(ulong*)ur->pc;
83 switch(getop(ir)) {
84 case 18: /* branch */
85 imm = ir & 0x03FFFFFC;
86 if(ir & 0x02000000)
87 imm |= 0xFC000000; /* sign extended */
88 if((ir & 2) == 0) /* relative address */
89 return ur->pc + imm;
90 return imm;
91
92 case 16: /* conditional branch */
93 if(condok(ur, ir&0xFFFF0000, 1)){
94 imm = ir & 0xFFFC;
95 if(ir & 0x08000)
96 imm |= 0xFFFF0000; /* sign extended */
97 if((ir & 2) == 0) /* relative address */
98 return ur->pc + imm;
99 return imm;
100 }
101 break;
102
103 case 19: /* conditional branch to register */
104 switch(getxo(ir)){
105 case 528: /* bcctr */
106 if(condok(ur, ir, 0))
107 return ur->ctr & ~3;
108 break;
109 case 16: /* bclr */
110 if(condok(ur, ir, 1))
111 return ur->lr & ~3;
112 break;
113 }
114 break;
115 }
116 return ur->pc+4; /* next instruction */
117 }
118
119 int
isvalid_va(void * v)120 isvalid_va(void *v)
121 {
122 return (ulong)v >= KTZERO;
123 }
124