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 }
}