mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-03 01:12:59 +00:00
[SparcV9] Adds support for branch on integer register instructions (BPr) and conditional moves on integer register (MOVr/FMOVr).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202628 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a9fe27ffb3
commit
2871375882
@ -39,6 +39,12 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
|
||||
case Sparc::fixup_sparc_br19:
|
||||
return (Value >> 2) & 0x7ffff;
|
||||
|
||||
case Sparc::fixup_sparc_br16_2:
|
||||
return (Value >> 2) & 0xc000;
|
||||
|
||||
case Sparc::fixup_sparc_br16_14:
|
||||
return (Value >> 2) & 0x3fff;
|
||||
|
||||
case Sparc::fixup_sparc_pc22:
|
||||
case Sparc::fixup_sparc_got22:
|
||||
case Sparc::fixup_sparc_tls_gd_hi22:
|
||||
@ -106,6 +112,8 @@ namespace {
|
||||
{ "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br16_2", 10, 2, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br16_14", 18, 14, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_hi22", 10, 22, 0 },
|
||||
{ "fixup_sparc_lo10", 22, 10, 0 },
|
||||
{ "fixup_sparc_h44", 10, 22, 0 },
|
||||
|
@ -26,6 +26,10 @@ namespace llvm {
|
||||
/// branches on icc/xcc
|
||||
fixup_sparc_br19,
|
||||
|
||||
/// fixup_sparc_bpr - 16-bit fixup for bpr
|
||||
fixup_sparc_br16_2,
|
||||
fixup_sparc_br16_14,
|
||||
|
||||
/// fixup_sparc_hi22 - 22-bit fixup corresponding to %hi(foo)
|
||||
/// for sethi
|
||||
fixup_sparc_hi22,
|
||||
|
@ -64,6 +64,10 @@ public:
|
||||
unsigned getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@ -192,6 +196,22 @@ getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo,
|
||||
(MCFixupKind)Sparc::fixup_sparc_br19));
|
||||
return 0;
|
||||
}
|
||||
unsigned SparcMCCodeEmitter::
|
||||
getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
if (MO.isReg() || MO.isImm())
|
||||
return getMachineOpValue(MI, MO, Fixups, STI);
|
||||
|
||||
Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
|
||||
(MCFixupKind)Sparc::fixup_sparc_br16_2));
|
||||
Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
|
||||
(MCFixupKind)Sparc::fixup_sparc_br16_14));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "SparcGenMCCodeEmitter.inc"
|
||||
|
@ -78,6 +78,8 @@ private:
|
||||
unsigned) const;
|
||||
unsigned getBranchPredTargetOpValue(const MachineInstr &MI,
|
||||
unsigned) const;
|
||||
unsigned getBranchOnRegTargetOpValue(const MachineInstr &MI,
|
||||
unsigned) const;
|
||||
|
||||
void emitWord(unsigned Word);
|
||||
|
||||
@ -206,6 +208,12 @@ unsigned SparcCodeEmitter::getBranchPredTargetOpValue(const MachineInstr &MI,
|
||||
return getMachineOpValue(MI, MO);
|
||||
}
|
||||
|
||||
unsigned SparcCodeEmitter::getBranchOnRegTargetOpValue(const MachineInstr &MI,
|
||||
unsigned opIdx) const {
|
||||
const MachineOperand MO = MI.getOperand(opIdx);
|
||||
return getMachineOpValue(MI, MO);
|
||||
}
|
||||
|
||||
unsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI,
|
||||
const MachineOperand &MO) const {
|
||||
|
||||
|
@ -344,6 +344,84 @@ def FMOVQ_XCC : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd),
|
||||
} // opf_cc
|
||||
} // Uses, Constraints
|
||||
|
||||
// Branch On integer register with Prediction (BPr).
|
||||
let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in
|
||||
multiclass BranchOnReg<bits<3> cond, string OpcStr> {
|
||||
def napt : F2_4<cond, 0, 1, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16),
|
||||
!strconcat(OpcStr, " $rs1, $imm16"), []>;
|
||||
def apt : F2_4<cond, 1, 1, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16),
|
||||
!strconcat(OpcStr, ",a $rs1, $imm16"), []>;
|
||||
def napn : F2_4<cond, 0, 0, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16),
|
||||
!strconcat(OpcStr, ",pn $rs1, $imm16"), []>;
|
||||
def apn : F2_4<cond, 1, 0, (outs), (ins I64Regs:$rs1, bprtarget16:$imm16),
|
||||
!strconcat(OpcStr, ",a,pn $rs1, $imm16"), []>;
|
||||
}
|
||||
|
||||
multiclass bpr_alias<string OpcStr, Instruction NAPT, Instruction APT> {
|
||||
def : InstAlias<!strconcat(OpcStr, ",pt $rs1, $imm16"),
|
||||
(NAPT I64Regs:$rs1, bprtarget16:$imm16)>;
|
||||
def : InstAlias<!strconcat(OpcStr, ",a,pt $rs1, $imm16"),
|
||||
(APT I64Regs:$rs1, bprtarget16:$imm16)>;
|
||||
}
|
||||
|
||||
defm BPZ : BranchOnReg<0b001, "brz">;
|
||||
defm BPLEZ : BranchOnReg<0b010, "brlez">;
|
||||
defm BPLZ : BranchOnReg<0b011, "brlz">;
|
||||
defm BPNZ : BranchOnReg<0b101, "brnz">;
|
||||
defm BPGZ : BranchOnReg<0b110, "brgz">;
|
||||
defm BPGEZ : BranchOnReg<0b111, "brgez">;
|
||||
|
||||
defm : bpr_alias<"brz", BPZnapt, BPZapt >;
|
||||
defm : bpr_alias<"brlez", BPLEZnapt, BPLEZapt>;
|
||||
defm : bpr_alias<"brlz", BPLZnapt, BPLZapt >;
|
||||
defm : bpr_alias<"brnz", BPNZnapt, BPNZapt >;
|
||||
defm : bpr_alias<"brgz", BPGZnapt, BPGZapt >;
|
||||
defm : bpr_alias<"brgez", BPGEZnapt, BPGEZapt>;
|
||||
|
||||
// Move integer register on register condition (MOVr).
|
||||
multiclass MOVR< bits<3> rcond, string OpcStr> {
|
||||
def rr : F4_4r<0b101111, 0b00000, rcond, (outs I64Regs:$rd),
|
||||
(ins I64Regs:$rs1, IntRegs:$rs2),
|
||||
!strconcat(OpcStr, " $rs1, $rs2, $rd"), []>;
|
||||
|
||||
def ri : F4_4i<0b101111, rcond, (outs I64Regs:$rd),
|
||||
(ins I64Regs:$rs1, i64imm:$simm10),
|
||||
!strconcat(OpcStr, " $rs1, $simm10, $rd"), []>;
|
||||
}
|
||||
|
||||
defm MOVRRZ : MOVR<0b001, "movrz">;
|
||||
defm MOVRLEZ : MOVR<0b010, "movrlez">;
|
||||
defm MOVRLZ : MOVR<0b011, "movrlz">;
|
||||
defm MOVRNZ : MOVR<0b101, "movrnz">;
|
||||
defm MOVRGZ : MOVR<0b110, "movrgz">;
|
||||
defm MOVRGEZ : MOVR<0b111, "movrgez">;
|
||||
|
||||
// Move FP register on integer register condition (FMOVr).
|
||||
multiclass FMOVR<bits<3> rcond, string OpcStr> {
|
||||
|
||||
def S : F4_4r<0b110101, 0b00101, rcond,
|
||||
(outs FPRegs:$rd), (ins I64Regs:$rs1, FPRegs:$rs2),
|
||||
!strconcat(!strconcat("fmovrs", OpcStr)," $rs1, $rs2, $rd"),
|
||||
[]>;
|
||||
def D : F4_4r<0b110101, 0b00110, rcond,
|
||||
(outs FPRegs:$rd), (ins I64Regs:$rs1, FPRegs:$rs2),
|
||||
!strconcat(!strconcat("fmovrd", OpcStr)," $rs1, $rs2, $rd"),
|
||||
[]>;
|
||||
def Q : F4_4r<0b110101, 0b00111, rcond,
|
||||
(outs FPRegs:$rd), (ins I64Regs:$rs1, FPRegs:$rs2),
|
||||
!strconcat(!strconcat("fmovrq", OpcStr)," $rs1, $rs2, $rd"),
|
||||
[]>, Requires<[HasHardQuad]>;
|
||||
}
|
||||
|
||||
let Predicates = [HasV9] in {
|
||||
defm FMOVRZ : FMOVR<0b001, "z">;
|
||||
defm FMOVRLEZ : FMOVR<0b010, "lez">;
|
||||
defm FMOVRLZ : FMOVR<0b011, "lz">;
|
||||
defm FMOVRNZ : FMOVR<0b101, "nz">;
|
||||
defm FMOVRGZ : FMOVR<0b110, "gz">;
|
||||
defm FMOVRGEZ : FMOVR<0b111, "gez">;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 64-bit Floating Point Conversions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -224,7 +224,6 @@ defm : fp_cond_alias<"le", 0b1101>;
|
||||
defm : fp_cond_alias<"ule", 0b1110>;
|
||||
defm : fp_cond_alias<"o", 0b1111>;
|
||||
|
||||
|
||||
// Instruction aliases for JMPL.
|
||||
|
||||
// jmp addr -> jmpl addr, %g0
|
||||
|
@ -77,6 +77,25 @@ class F2_3<bits<3> op2Val, bit annul, bit pred,
|
||||
let Inst{18-0} = imm19;
|
||||
}
|
||||
|
||||
class F2_4<bits<3> cond, bit annul, bit pred,
|
||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstSP<outs, ins, asmstr, pattern> {
|
||||
bits<16> imm16;
|
||||
bits<5> rs1;
|
||||
|
||||
let op = 0; // op = 0
|
||||
|
||||
let Inst{29} = annul;
|
||||
let Inst{28} = 0;
|
||||
let Inst{27-25} = cond;
|
||||
let Inst{24-22} = 0b011;
|
||||
let Inst{21-20} = imm16{15-14};
|
||||
let Inst{19} = pred;
|
||||
let Inst{18-14} = rs1;
|
||||
let Inst{13-0} = imm16{13-0};
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Format #3 instruction classes in the Sparc
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -254,3 +273,27 @@ class F4_3<bits<6> op3, bits<6> opf_low, dag outs, dag ins,
|
||||
let Inst{10-5} = opf_low;
|
||||
let Inst{4-0} = rs2;
|
||||
}
|
||||
|
||||
class F4_4r<bits<6> op3, bits<5> opf_low, bits<3> rcond, dag outs, dag ins,
|
||||
string asmstr, list<dag> pattern>
|
||||
: F4<op3, outs, ins, asmstr, pattern> {
|
||||
bits <5> rs1;
|
||||
bits <5> rs2;
|
||||
let Inst{18-14} = rs1;
|
||||
let Inst{13} = 0; // IsImm
|
||||
let Inst{12-10} = rcond;
|
||||
let Inst{9-5} = opf_low;
|
||||
let Inst{4-0} = rs2;
|
||||
}
|
||||
|
||||
|
||||
class F4_4i<bits<6> op3, bits<3> rcond, dag outs, dag ins,
|
||||
string asmstr, list<dag> pattern>
|
||||
: F4<op3, outs, ins, asmstr, pattern> {
|
||||
bits<5> rs1;
|
||||
bits<10> simm10;
|
||||
let Inst{18-14} = rs1;
|
||||
let Inst{13} = 1; // IsImm
|
||||
let Inst{12-10} = rcond;
|
||||
let Inst{9-0} = simm10;
|
||||
}
|
||||
|
@ -109,6 +109,10 @@ def bprtarget : Operand<OtherVT> {
|
||||
let EncoderMethod = "getBranchPredTargetOpValue";
|
||||
}
|
||||
|
||||
def bprtarget16 : Operand<OtherVT> {
|
||||
let EncoderMethod = "getBranchOnRegTargetOpValue";
|
||||
}
|
||||
|
||||
def calltarget : Operand<i32> {
|
||||
let EncoderMethod = "getCallTargetOpValue";
|
||||
let DecoderMethod = "DecodeCall";
|
||||
|
@ -1136,3 +1136,81 @@
|
||||
! CHECK: fbne,a,pn %fcc3, .BB0 ! encoding: [0x23,0b01110AAA,A,A]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
|
||||
fbne,a,pn %fcc3, .BB0
|
||||
|
||||
|
||||
! CHECK: brz %g1, .BB0 ! encoding: [0x02,0b11AA1000,0b01BBBBBB,B]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
|
||||
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
|
||||
! CHECK: brlez %g1, .BB0 ! encoding: [0x04,0b11AA1000,0b01BBBBBB,B]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
|
||||
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
|
||||
! CHECK: brlz %g1, .BB0 ! encoding: [0x06,0b11AA1000,0b01BBBBBB,B]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
|
||||
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
|
||||
! CHECK: brnz %g1, .BB0 ! encoding: [0x0a,0b11AA1000,0b01BBBBBB,B]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
|
||||
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
|
||||
! CHECK: brgz %g1, .BB0 ! encoding: [0x0c,0b11AA1000,0b01BBBBBB,B]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
|
||||
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
|
||||
! CHECK: brgez %g1, .BB0 ! encoding: [0x0e,0b11AA1000,0b01BBBBBB,B]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
|
||||
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
|
||||
|
||||
brz %g1, .BB0
|
||||
brlez %g1, .BB0
|
||||
brlz %g1, .BB0
|
||||
brnz %g1, .BB0
|
||||
brgz %g1, .BB0
|
||||
brgez %g1, .BB0
|
||||
|
||||
! CHECK: brz %g1, .BB0 ! encoding: [0x02,0b11AA1000,0b01BBBBBB,B]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
|
||||
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
|
||||
brz,pt %g1, .BB0
|
||||
|
||||
! CHECK: brz,a %g1, .BB0 ! encoding: [0x22,0b11AA1000,0b01BBBBBB,B]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
|
||||
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
|
||||
brz,a %g1, .BB0
|
||||
|
||||
! CHECK: brz,a %g1, .BB0 ! encoding: [0x22,0b11AA1000,0b01BBBBBB,B]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
|
||||
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
|
||||
brz,a,pt %g1, .BB0
|
||||
|
||||
! CHECK: brz,pn %g1, .BB0 ! encoding: [0x02,0b11AA0000,0b01BBBBBB,B]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
|
||||
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
|
||||
brz,pn %g1, .BB0
|
||||
|
||||
! CHECK: brz,a,pn %g1, .BB0 ! encoding: [0x22,0b11AA0000,0b01BBBBBB,B]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
|
||||
! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
|
||||
brz,a,pn %g1, .BB0
|
||||
|
||||
! CHECK: movrz %g1, %g2, %g3 ! encoding: [0x87,0x78,0x44,0x02]
|
||||
! CHECK: movrlez %g1, %g2, %g3 ! encoding: [0x87,0x78,0x48,0x02]
|
||||
! CHECK: movrlz %g1, %g2, %g3 ! encoding: [0x87,0x78,0x4c,0x02]
|
||||
! CHECK: movrnz %g1, %g2, %g3 ! encoding: [0x87,0x78,0x54,0x02]
|
||||
! CHECK: movrgz %g1, %g2, %g3 ! encoding: [0x87,0x78,0x58,0x02]
|
||||
! CHECK: movrgez %g1, %g2, %g3 ! encoding: [0x87,0x78,0x5c,0x02]
|
||||
movrz %g1, %g2, %g3
|
||||
movrlez %g1, %g2, %g3
|
||||
movrlz %g1, %g2, %g3
|
||||
movrnz %g1, %g2, %g3
|
||||
movrgz %g1, %g2, %g3
|
||||
movrgez %g1, %g2, %g3
|
||||
|
||||
! CHECK: fmovrsz %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x44,0xa2]
|
||||
! CHECK: fmovrslez %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x48,0xa2]
|
||||
! CHECK: fmovrslz %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x4c,0xa2]
|
||||
! CHECK: fmovrsnz %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x54,0xa2]
|
||||
! CHECK: fmovrsgz %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x58,0xa2]
|
||||
! CHECK: fmovrsgez %g1, %f2, %f3 ! encoding: [0x87,0xa8,0x5c,0xa2]
|
||||
fmovrsz %g1, %f2, %f3
|
||||
fmovrslez %g1, %f2, %f3
|
||||
fmovrslz %g1, %f2, %f3
|
||||
fmovrsnz %g1, %f2, %f3
|
||||
fmovrsgz %g1, %f2, %f3
|
||||
fmovrsgez %g1, %f2, %f3
|
||||
|
Loading…
Reference in New Issue
Block a user