Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

branchem.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 branchem.c 00008 00009 Abstract: 00010 00011 This module implement the code necessary to emulate branches when an 00012 alignment or floating exception occurs in the delay slot of a branch 00013 instruction. 00014 00015 Author: 00016 00017 David N. Cutler (davec) 17-Jun-1991 00018 00019 Environment: 00020 00021 Kernel mode only. 00022 00023 Revision History: 00024 00025 --*/ 00026 00027 #include "ki.h" 00028 00029 ULONG 00030 KiEmulateBranch ( 00031 IN PKEXCEPTION_FRAME ExceptionFrame, 00032 IN PKTRAP_FRAME TrapFrame 00033 ) 00034 00035 /*++ 00036 00037 Routine Description: 00038 00039 This function is called to emulate the branch instruction specified by 00040 the fault instruction address in the specified trap frame. The resultant 00041 branch destination address is computed and returned as the function value. 00042 00043 Arguments: 00044 00045 ExceptionFrame - Supplies a pointer to an exception frame. 00046 00047 TrapFrame - Supplies a pointer to a trap frame. 00048 00049 Return Value: 00050 00051 The resultant target branch destination is returned as the function value. 00052 00053 --*/ 00054 00055 { 00056 00057 MIPS_INSTRUCTION BranchInstruction; 00058 ULONG BranchTaken; 00059 ULONG BranchNotTaken; 00060 ULONG RsValue; 00061 ULONG RtValue; 00062 00063 // 00064 // Get the branch instruction at the fault address. 00065 // 00066 00067 BranchInstruction.Long = *((PULONG)TrapFrame->Fir); 00068 00069 // 00070 // Assume the branch instruction is a conditional branch and get the 00071 // Rs and Rt register values. Also compute the branch taken as well 00072 // as the branch not taken target addresses. 00073 // 00074 00075 RsValue = KiGetRegisterValue(BranchInstruction.r_format.Rs, 00076 ExceptionFrame, 00077 TrapFrame); 00078 00079 RtValue = KiGetRegisterValue(BranchInstruction.r_format.Rt, 00080 ExceptionFrame, 00081 TrapFrame); 00082 00083 BranchTaken = (TrapFrame->Fir + 4) + 00084 (LONG)(BranchInstruction.i_format.Simmediate << 2); 00085 BranchNotTaken = TrapFrame->Fir + 8; 00086 00087 // 00088 // Dispatch on the opcode value. 00089 // 00090 // N.B. All branch likely instructions are guaranteed to branch since an 00091 // exception would not have been generated in the delay slot if the 00092 // the branch was not going to actually branch. 00093 // 00094 00095 switch (BranchInstruction.r_format.Opcode) { 00096 00097 // 00098 // Special opcode - dispatch on the function subopcode. 00099 // 00100 00101 case SPEC_OP: 00102 switch (BranchInstruction.r_format.Function) { 00103 00104 // 00105 // Jalr - jump and link register. 00106 // 00107 // N.B. Ra has already been loaded by the hardware before the 00108 // exception condition occurred. 00109 // 00110 00111 case JALR_OP: 00112 00113 // 00114 // Jr - jump register. 00115 // 00116 00117 case JR_OP: 00118 return RsValue; 00119 00120 // 00121 // All other instruction are illegal and should never happen. 00122 // 00123 00124 default: 00125 return TrapFrame->Fir; 00126 } 00127 00128 // 00129 // Jal - jump and link. 00130 // 00131 // N.B. Ra has already been loaded by the hardware before the 00132 // exception condition occurred. 00133 // 00134 00135 case JAL_OP: 00136 00137 // 00138 // J - jump. 00139 // 00140 00141 case J_OP: 00142 return ((TrapFrame->Fir + 4) & 0xf0000000) | 00143 (BranchInstruction.j_format.Target << 2); 00144 00145 // 00146 // Beq - branch equal. 00147 // Beql - branch equal likely. 00148 // 00149 00150 case BEQ_OP: 00151 case BEQL_OP: 00152 if ((LONG)RsValue == (LONG)RtValue) { 00153 return BranchTaken; 00154 00155 } else { 00156 return BranchNotTaken; 00157 } 00158 00159 // 00160 // Bne - branch not equal. 00161 // Bnel - branch not equal likely. 00162 // 00163 00164 case BNE_OP: 00165 case BNEL_OP: 00166 if ((LONG)RsValue != (LONG)RtValue) { 00167 return BranchTaken; 00168 00169 } else { 00170 return BranchNotTaken; 00171 } 00172 00173 // 00174 // Blez - branch less than or equal zero. 00175 // Blezl - branch less than or equal zero likely. 00176 // 00177 00178 case BLEZ_OP: 00179 case BLEZL_OP: 00180 if ((LONG)RsValue <= 0) { 00181 return BranchTaken; 00182 00183 } else { 00184 return BranchNotTaken; 00185 } 00186 00187 // 00188 // Bgtz - branch greater than zero. 00189 // Bgtzl - branch greater than zero likely. 00190 // 00191 00192 case BGTZ_OP: 00193 case BGTZL_OP: 00194 if ((LONG)RsValue > 0) { 00195 return BranchTaken; 00196 00197 } else { 00198 return BranchNotTaken; 00199 } 00200 00201 // 00202 // Branch conditional opcode - dispatch on the rt field. 00203 // 00204 00205 case BCOND_OP: 00206 switch (BranchInstruction.r_format.Rt) { 00207 00208 // 00209 // Bltzal - branch on less than zero and link. 00210 // Bltzall - branch on less than zero and link likely. 00211 // 00212 // N.B. Ra has already been loaded by the hardware before the 00213 // exception condition occurred. 00214 // 00215 00216 case BLTZAL_OP: 00217 case BLTZALL_OP: 00218 00219 // 00220 // Bltz - branch less than zero. 00221 // Bltzl - branch less than zero likely. 00222 // 00223 00224 case BLTZ_OP: 00225 case BLTZL_OP: 00226 if ((LONG)RsValue < 0) { 00227 return BranchTaken; 00228 00229 } else { 00230 return BranchNotTaken; 00231 } 00232 00233 // 00234 // Bgezal - branch on greater than or euqal zero and link. 00235 // Bgezall - branch on greater than or equal zero and link likely. 00236 // 00237 // N.B. Ra has already been loaded by the hardware before the 00238 // exception condition occurred. 00239 // 00240 00241 case BGEZAL_OP: 00242 case BGEZALL_OP: 00243 00244 // 00245 // Bgez - branch greater than zero. 00246 // Bgezl - branch greater than zero likely. 00247 // 00248 00249 case BGEZ_OP: 00250 case BGEZL_OP: 00251 if ((LONG)RsValue >= 0) { 00252 return BranchTaken; 00253 00254 } else { 00255 return BranchNotTaken; 00256 } 00257 00258 // 00259 // All other instructions are illegal and should not happen. 00260 // 00261 00262 default: 00263 return TrapFrame->Fir; 00264 } 00265 00266 // 00267 // Cop1 - coprocessor 1 branch operation. 00268 // 00269 // Bczf - Branch coprocessor z false. 00270 // Bczfl - Branch coprocessor z false likely. 00271 // Bczt - Branch coprocessor z true. 00272 // Bcztl - Branch coprocessor z true likely. 00273 // 00274 00275 case COP1_OP: 00276 if ((BranchInstruction.Long & COPz_BC_MASK) == COPz_BF) { 00277 00278 // 00279 // Branch on coprocessor 1 condition code false. 00280 // 00281 00282 if (((PFSR)(&TrapFrame->Fsr))->CC == 0) { 00283 return BranchTaken; 00284 00285 } else { 00286 return BranchNotTaken; 00287 } 00288 00289 } else if ((BranchInstruction.Long & COPz_BC_MASK) == COPz_BT) { 00290 00291 // 00292 // Branch of coprocessor 1 condition code true. 00293 // 00294 00295 if (((PFSR)(&TrapFrame->Fsr))->CC != 0) { 00296 return BranchTaken; 00297 00298 } else { 00299 return BranchNotTaken; 00300 } 00301 00302 } 00303 00304 // 00305 // All other instructions are illegal and should not happen. 00306 // 00307 00308 default: 00309 return TrapFrame->Fir; 00310 } 00311 }

Generated on Sat May 15 19:39:18 2004 for test by doxygen 1.3.7