00037                    :
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     
00065     
00066 
00067     BranchInstruction.Long = *((PULONG)TrapFrame->Fir);
00068 
00069     
00070     
00071     
00072     
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     
00089     
00090     
00091     
00092     
00093     
00094 
00095     
switch (BranchInstruction.r_format.Opcode) {
00096 
00097         
00098         
00099         
00100 
00101     
case SPEC_OP:
00102         
switch (BranchInstruction.r_format.Function) {
00103 
00104             
00105             
00106             
00107             
00108             
00109             
00110 
00111         
case JALR_OP:
00112 
00113             
00114             
00115             
00116 
00117         
case JR_OP:
00118             
return RsValue;
00119 
00120             
00121             
00122             
00123 
00124         
default:
00125             
return TrapFrame->Fir;
00126         }
00127 
00128         
00129         
00130         
00131         
00132         
00133         
00134 
00135     
case JAL_OP:
00136 
00137         
00138         
00139         
00140 
00141     
case J_OP:
00142         
return ((TrapFrame->Fir + 4) & 0xf0000000) |
00143                                         (BranchInstruction.j_format.Target << 2);
00144 
00145         
00146         
00147         
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         
00161         
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         
00175         
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         
00189         
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         
00203         
00204 
00205     
case BCOND_OP:
00206         
switch (BranchInstruction.r_format.Rt) {
00207 
00208             
00209             
00210             
00211             
00212             
00213             
00214             
00215 
00216         
case BLTZAL_OP:
00217         
case BLTZALL_OP:
00218 
00219             
00220             
00221             
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             
00235             
00236             
00237             
00238             
00239             
00240 
00241         
case BGEZAL_OP:
00242         
case BGEZALL_OP:
00243 
00244             
00245             
00246             
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             
00260             
00261 
00262         
default:
00263             
return TrapFrame->Fir;
00264         }
00265 
00266         
00267         
00268         
00269         
00270         
00271         
00272         
00273         
00274 
00275     
case COP1_OP:
00276         
if ((BranchInstruction.Long & COPz_BC_MASK) == COPz_BF) {
00277 
00278             
00279             
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             
00293             
00294 
00295             
if (((PFSR)(&TrapFrame->Fsr))->CC != 0) {
00296                 
return BranchTaken;
00297 
00298             } 
else {
00299                 
return BranchNotTaken;
00300             }
00301 
00302         }
00303 
00304         
00305         
00306         
00307 
00308     
default:
00309         
return TrapFrame->Fir;
00310     }
00311 }
}