* Return the resulting PC as if the branch was executed. */
| 1156 | * Return the resulting PC as if the branch was executed. |
| 1157 | */ |
| 1158 | uintptr_t |
| 1159 | MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR, |
| 1160 | uintptr_t instptr) |
| 1161 | { |
| 1162 | InstFmt inst; |
| 1163 | register_t *regsPtr = (register_t *) framePtr; |
| 1164 | uintptr_t retAddr = 0; |
| 1165 | int condition; |
| 1166 | |
| 1167 | #define GetBranchDest(InstPtr, inst) \ |
| 1168 | (InstPtr + 4 + ((short)inst.IType.imm << 2)) |
| 1169 | |
| 1170 | if (instptr) { |
| 1171 | if (instptr < MIPS_KSEG0_START) |
| 1172 | inst.word = fuword32((void *)instptr); |
| 1173 | else |
| 1174 | inst = *(InstFmt *) instptr; |
| 1175 | } else { |
| 1176 | if ((vm_offset_t)instPC < MIPS_KSEG0_START) |
| 1177 | inst.word = fuword32((void *)instPC); |
| 1178 | else |
| 1179 | inst = *(InstFmt *) instPC; |
| 1180 | } |
| 1181 | |
| 1182 | switch ((int)inst.JType.op) { |
| 1183 | case OP_SPECIAL: |
| 1184 | switch ((int)inst.RType.func) { |
| 1185 | case OP_JR: |
| 1186 | case OP_JALR: |
| 1187 | retAddr = regsPtr[inst.RType.rs]; |
| 1188 | break; |
| 1189 | |
| 1190 | default: |
| 1191 | retAddr = instPC + 4; |
| 1192 | break; |
| 1193 | } |
| 1194 | break; |
| 1195 | |
| 1196 | case OP_BCOND: |
| 1197 | switch ((int)inst.IType.rt) { |
| 1198 | case OP_BLTZ: |
| 1199 | case OP_BLTZL: |
| 1200 | case OP_BLTZAL: |
| 1201 | case OP_BLTZALL: |
| 1202 | if ((int)(regsPtr[inst.RType.rs]) < 0) |
| 1203 | retAddr = GetBranchDest(instPC, inst); |
| 1204 | else |
| 1205 | retAddr = instPC + 8; |
| 1206 | break; |
| 1207 | |
| 1208 | case OP_BGEZ: |
| 1209 | case OP_BGEZL: |
| 1210 | case OP_BGEZAL: |
| 1211 | case OP_BGEZALL: |
| 1212 | if ((int)(regsPtr[inst.RType.rs]) >= 0) |
| 1213 | retAddr = GetBranchDest(instPC, inst); |
| 1214 | else |
| 1215 | retAddr = instPC + 8; |
no test coverage detected