Merge pull request #311 from jpenalbae/sparc-branchfix

Sparc conditional branches displacement fix
This commit is contained in:
Nguyen Anh Quynh 2015-04-13 22:21:53 +08:00
commit 094ae1e323
1 changed files with 69 additions and 6 deletions

View File

@ -188,12 +188,75 @@ static void printOperand(MCInst *MI, int opNum, SStream *O)
if (MCOperand_isImm(MO)) {
Imm = (int)MCOperand_getImm(MO);
// get absolute address for CALL/Bxx
if (MI->Opcode == SP_CALL)
Imm += (uint32_t)MI->address;
else if (MI->flat_insn->id == SPARC_INS_B)
// pc + (disp30 * 4)
Imm = (uint32_t)MI->address + Imm * 4;
// Conditional branches displacements needs to be signextended to be
// able to jump backwards.
//
// Displacements are measured as the number of instructions forward or
// backward, so they need to be multiplied by 4
switch (MI->Opcode) {
case SP_CALL:
Imm = SignExtend32(Imm, 30);
Imm += (uint32_t)MI->address;
break;
// Branch on integer condition with prediction (BPcc)
// Branch on floating point condition with prediction (FBPfcc)
case SP_BPICC:
case SP_BPICCA:
case SP_BPICCANT:
case SP_BPICCNT:
case SP_BPXCC:
case SP_BPXCCA:
case SP_BPXCCANT:
case SP_BPXCCNT:
case SP_BPFCC:
case SP_BPFCCA:
case SP_BPFCCANT:
case SP_BPFCCNT:
Imm = SignExtend32(Imm, 19);
Imm = (uint32_t)MI->address + Imm * 4;
break;
// Branch on integer condition (Bicc)
// Branch on floating point condition (FBfcc)
case SP_BA:
case SP_BCOND:
case SP_BCONDA:
case SP_FBCOND:
case SP_FBCONDA:
Imm = SignExtend32(Imm, 22);
Imm = (uint32_t)MI->address + Imm * 4;
break;
// Branch on integer register with prediction (BPr)
case SP_BPGEZapn:
case SP_BPGEZapt:
case SP_BPGEZnapn:
case SP_BPGEZnapt:
case SP_BPGZapn:
case SP_BPGZapt:
case SP_BPGZnapn:
case SP_BPGZnapt:
case SP_BPLEZapn:
case SP_BPLEZapt:
case SP_BPLEZnapn:
case SP_BPLEZnapt:
case SP_BPLZapn:
case SP_BPLZapt:
case SP_BPLZnapn:
case SP_BPLZnapt:
case SP_BPNZapn:
case SP_BPNZapt:
case SP_BPNZnapn:
case SP_BPNZnapt:
case SP_BPZapn:
case SP_BPZapt:
case SP_BPZnapn:
case SP_BPZnapt:
Imm = SignExtend32(Imm, 16);
Imm = (uint32_t)MI->address + Imm * 4;
break;
}
if (Imm >= 0) {
if (Imm > HEX_THRESHOLD)