test: branchem.c Source File

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 }