br Operation Font Conventions
if (ip_relative_form) // determine branch
target
tmp_IP = IP + sign_ext((imm21
<< 4), 25);
else // indirect_form
tmp_IP = BR[b2];
if (btype != ‘ia') // for Itanium
tmp_IP = tmp_IP & ~0xf; // ignore bottom 4 bits of target
lower_priv_transition = 0;
switch (btype) {
case ‘cond': // simple conditional branch
tmp_taken = PR[qp];
break;
case ‘call': // call saves a return link
tmp_taken = PR[qp];
if (tmp_taken) {
BR[b1] = IP + 16;
AR[PFS].pfm = CFM; // ... and saves the stack frame
AR[PFS].pec = AR[EC];
AR[PFS].ppl = PSR.cpl;
alat_frame_update(CFM.sol, 0);
rse_preserve_frame(CFM.sol);
CFM.sof -= CFM.sol; // new frame size is size of outs
CFM.sol = 0;
CFM.sor = 0;
CFM.rrb.gr = 0;
CFM.rrb.fr = 0;
CFM.rrb.pr = 0;
}
break;
case ‘ret': // return restores stack frame
tmp_taken = PR[qp];
if (tmp_taken) {
// tmp_growth indicates the amount to move logical TOP *up*:
// tmp_growth = sizeof(previous out) - sizeof(current frame)
// a negative amount indicates a shrinking stack
tmp_growth = (AR[PFS].pfm.sof - AR[PFS].pfm.sol) - CFM.sof;
alat_frame_update(-AR[PFS].pfm.sol, 0);
rse_fatal = rse_restore_frame(AR[PFS].pfm.sol, tmp_growth,
CFM.sof);
if (rse_fatal) { CFM.sof = 0;
CFM.sol = 0;
CFM.sor = 0;
CFM.rrb.gr = 0;
CFM.rrb.fr = 0;
CFM.rrb.pr = 0;
} else // normal branch return
CFM = AR[PFS].pfm;
rse_enable_current_frame_load();
AR[EC] = AR[PFS].pec;
if (PSR.cpl u< AR[PFS].ppl) {// ... and restores privilege
PSR.cpl = AR[PFS].ppl;
lower_priv_transition = 1;
}
}
break;
case ‘ia': // switch to IA mode
tmp_taken = 1;
if (qp != 0)
illegal_operation_fault();
if (AR[BSPSTORE] != AR[BSP])
illegal_operation_fault();
if (PSR.di)
disabled_instruction_set_transition_fault();
PSR.is = 1; // set IA-32 Instruction Set Mode
CFM.sof = 0; //force current stack frame
CFM.sol = 0; //to zero
CFM.sor = 0;
CFM.rrb.gr = 0;
CFM.rrb.fr = 0;
CFM.rrb.pr = 0;
rse_invalidate_non_current_regs();
// compute linear instruction pointer
tmp_IP = zero_ext(tmp_IP{31:0}, 32);
//compute effective instruction pointer
EIP{31:0} = tmp_IP{31:0} - AR[CSD].Base;
// Note the register stack is disabled during IA-32 instruction set execution
break;
case ‘cloop': // simple counted loop
if (slot != 2)
illegal_operation_fault();
tmp_taken = (AR[LC] != 0);
if (AR[LC] != 0)
AR[LC]--;
break;
case ‘ctop':
case ‘cexit': // SW pipelined counted loop
if (slot != 2)
illegal_operation_fault();
if (btype == ‘ctop') tmp_taken
= ((AR[LC] != 0) || (AR[EC] u> 1));
if (btype == ‘cexit') tmp_taken
= !((AR[LC] != 0) || (AR[EC] u> 1));
if (AR[LC] != 0) {
AR[LC]--;
AR[EC] = AR[EC];
PR[63] = 1;
rotate_regs();
} else if (AR[EC] != 0) {
AR[LC] = AR[LC];
AR[EC]--;
PR[63] = 0;
rotate_regs();
} else {
AR[LC] = AR[LC];
AR[EC] = AR[EC];
PR[63] = 0;
CFM.rrb.gr = CFM.rrb.gr;
CFM.rrb.fr = CFM.rrb.fr;
CFM.rrb.pr = CFM.rrb.pr;
}
break;
case ‘wtop':
case ‘wexit': // SW pipelined while loop
if (slot != 2)
illegal_operation_fault();
if (btype == ‘wtop') tmp_taken
= (PR[qp] || (AR[EC] u>
1));
if (btype == ‘wexit') tmp_taken
= !(PR[qp] || (AR[EC] u> 1));
if (PR[qp]) {
AR[EC] = AR[EC];
PR[63] = 0;
rotate_regs();
} else if (AR[EC] != 0) {
AR[EC]--;
PR[63] = 0;
rotate_regs();
} else {
AR[EC] = AR[EC];
PR[63] = 0;
CFM.rrb.gr = CFM.rrb.gr;
CFM.rrb.fr = CFM.rrb.fr;
CFM.rrb.pr = CFM.rrb.pr;
}
break;
}
if (tmp_taken) {
taken_branch = 1;
IP = tmp_IP; // set the new value for IP
if ((PSR.it && unimplemented_virtual_address(tmp_IP))
|| (!PSR.it && unimplemented_physical_address(tmp_IP)))
unimplemented_instruction_address_trap(lower_priv_transition,tmp_IP);
if (lower_priv_transition && PSR.lp)
lower_privilege_transfer_trap();
if (PSR.tb)
taken_branch_trap();
}