diff --git a/llvm/lib/Target/Sparc/SparcV9.td b/llvm/lib/Target/Sparc/SparcV9.td new file mode 100644 index 000000000000..8979e3851268 --- /dev/null +++ b/llvm/lib/Target/Sparc/SparcV9.td @@ -0,0 +1,359 @@ +//===- Sparc.td - Target Description for Sparc V9 Target --------*- C++ -*-===// +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Target-Independent interface +//===----------------------------------------------------------------------===// + +class Register { + string Namespace = ""; + int Size; +} + +class Instruction { + string Name; // The opcode string for this instruction + string Namespace = ""; + + list Uses = []; // Default to using no non-operand registers + list Defs = []; // Default to modifying no non-operand registers + + // These bits capture information about the high-level semantics of the + // instruction. + bit isReturn = 0; // Is this instruction a return instruction? + bit isBranch = 0; // Is this instruction a branch instruction? + bit isCall = 0; // Is this instruction a call instruction? +} + + +//===----------------------------------------------------------------------===// +// Declarations that describe the Sparc register file +//===----------------------------------------------------------------------===// + +class V9Reg : Register { set Namespace = "SparcV9"; } + +// Ri - One of the 32 64 bit integer registers +class Ri num> : V9Reg { set Size = 64; field bits<5> Num = num; } + +def G0 : Ri<0>; def G1 : Ri<1>; def G2 : Ri<2>; def G3 : Ri<3>; +// ... + + +//===----------------------------------------------------------------------===// +// This is temporary testing stuff..... +//===----------------------------------------------------------------------===// + +class InstV9 : Instruction { // Sparc instruction baseline + field bits<32> Inst; + + set Namespace = "SparcV9"; + + bits<2> op; + set Inst{31-30} = op; // Top two bits are the 'op' field + + // Bit attributes specific to Sparc instructions + bit isPasi = 0; // Does this instruction affect an alternate addr space? + bit isDeprecated = 0; // Is this instruction deprecated? + bit isPrivileged = 0; // Is this a privileged instruction? +} + + +//===----------------------------------------------------------------------===// +// Format #2 classes +// +class F2 : InstV9 { // Format 2 instructions + bits<3> op2; + set op = 0; // Op = 0 + set Inst{24-22} = op2; +} + +class F2_br : F2 { // Format 2 Branch instruction + bit annul; // All branches have an annul bit + set Inst{29} = annul; + set isBranch = 1; // All instances are branch instructions +} + +class F2_2 cond, string name> : F2_br { // Format 2.2 instructions + bits<22> disp; + + set Name = name; + set Inst{28-25} = cond; + set Inst{21-0} = disp; +} + +class F2_3 cond, string name> : F2_br { // Format 2.3 instructions + bits<2> cc; + bits<19> disp; + bit predict; + + set Name = name; + set Inst{28-25} = cond; + set Inst{21-20} = cc; + set Inst{19} = predict; + set Inst{18-0} = disp; +} + +class F2_4 rcond, string name> : F2_br { // Format 2.4 instructions + // Variables exposed by the instruction... + bit predict; + bits<5> rs1; + bits<16> disp; + + set Name = name; + set Inst{28} = 0; + set Inst{27-25} = rcond; + // Inst{24-22} = op2 field + set Inst{21-20} = disp{15-14}; + set Inst{19} = predict; + set Inst{18-14} = rs1; + set Inst{13-0 } = disp{13-0}; +} + + +//===----------------------------------------------------------------------===// +// Format #3 classes +// + +// F3 - Common superclass of all F3 instructions. All instructions have an op3 +// field. +class F3 : InstV9 { + bits<6> op3; + set op{1} = 1; // Op = 2 or 3 + set Inst{24-19} = op3; +} + +// F3_rs1 - Common superclass of instructions that use rs1 +class F3_rs1 : F3 { + bits<5> rs1; + set Inst{18-14} = rs1; +} + +// F3_rs1rd - Common superclass of instructions that use rs1 & rd... +class F3_rs1rd : F3_rs1 { + bits<5> rd; + set Inst{29-25} = rd; +} + +// F3_rs1rdrs2 - Common superclass of instructions with rs1, rd, & rs2 fields +class F3_rs1rdrs2 : F3_rs1 { + bits<5> rs2; + set Inst{4-0} = rs2; +} + +// Specific F3 classes... +// + +class F3_1 opVal, bits<6> op3val, string name> : F3_rs1rdrs2 { + set op = opVal; + set op3 = op3val; + set Name = name; + set Inst{13} = 0; // i field = 0 + //set Inst{12-5} = dontcare; +} + +class F3_2 opVal, bits<6> op3val, string name> : F3_rs1rd { + bits<13> simm; + + set op = opVal; + set op3 = op3val; + set Name = name; + set Inst{13} = 1; // i field = 1 + set Inst{12-0} = simm; +} + +class F3_3 opVal, bits<6> op3val, string name> : F3_rs1 { + bits<5> rs2; + set op = opVal; + set op3 = op3val; + set Name = name; + //set Inst{29-25} = dontcare; + set Inst{13} = 0; + //set Inst{12-5} = dontcare; + set Inst{4-0} = rs2; +} + +class F3_4 opVal, bits<6> op3val, string name> : F3_rs1 { + bits<13> simm; + set op = opVal; + set op3 = op3val; + set Name = name; + //set Inst{29-25} = dontcare; + set Inst{13} = 1; + set Inst{12-0} = simm; +} + + + +class F3_16 opVal, bits<6> op3val, + bits<9> opfval, string name> : F3_rs1rdrs2 { + set op = opVal; + set op3 = op3val; + set Name = name; + set Inst{13-5} = opfval; +} + +class F3_18 fcn, string name> : F3 { + set op = 2; + set op3 = 0b111110; + set Name = name; + set Inst{29-25} = fcn; + //set Inst{18-0 } = dontcare; +} + +//===----------------------------------------------------------------------===// +// Instruction list... +// + +// Section A.2: p161 +def ADDr : F3_1<2, 0b000000, "add">; // add r, r, r +def ADDi : F3_2<2, 0b000000, "add">; // add r, r, i +def ADDCCr : F3_1<2, 0b010000, "addcc">; // addcc r, r, r +def ADDCCi : F3_2<2, 0b010000, "addcc">; // addcc r, r, i +def ADDCr : F3_1<2, 0b001000, "addC">; // addC r, r, r +def ADDCi : F3_2<2, 0b001000, "addC">; // addC r, r, i +def ADDCCCr : F3_1<2, 0b011000, "addCcc">; // addCcc r, r, r +def ADDCCCi : F3_2<2, 0b011000, "addCcc">; // addCcc r, r, i + +// Section A.3: p162 +set op2 = 0b011 in { + def BRZ : F2_4<0b001, "brz">; // Branch on rs1 == 0 + def BRLEZ : F2_4<0b010, "brlez">; // Branch on rs1 <= 0 + def BRLZ : F2_4<0b011, "brlz">; // Branch on rs1 < 0 + def BRNZ : F2_4<0b101, "brnz">; // Branch on rs1 != 0 + def BRGZ : F2_4<0b110, "brgz">; // Branch on rs1 > 0 + def BRGEZ : F2_4<0b111, "brgez">; // Branch on rs1 >= 0 +} + +// Section A.4: p164 +set isDeprecated = 1 in { + set op2 = 0b110 in { + def FBA : F2_2<0b1000, "fba">; // Branch always + def FBN : F2_2<0b0000, "fbn">; // Branch never + def FBU : F2_2<0b0111, "fbu">; // Branch on unordered + def FBG : F2_2<0b0110, "fbg">; // Branch > + def FBUG : F2_2<0b0101, "fbug">; // Branch on unordered or > + def FBL : F2_2<0b0100, "fbl">; // Branch < + def FBUL : F2_2<0b0011, "fbul">; // Branch on unordered or < + def FBLG : F2_2<0b0010, "fblg">; // Branch < or > + def FBNE : F2_2<0b0001, "fbne">; // Branch != + def FBE : F2_2<0b1001, "fbe">; // Branch == + def FBUE : F2_2<0b1010, "fbue">; // Branch on unordered or == + def FBGE : F2_2<0b1011, "fbge">; // Branch > or == + def FBUGE : F2_2<0b1100, "fbuge">; // Branch unord or > or == + def FBLE : F2_2<0b1101, "fble">; // Branch < or == + def FBULE : F2_2<0b1110, "fbule">; // Branch unord or < or == + def FBO : F2_2<0b1111, "fbo">; // Branch on ordered + } +} + +// Section A.5: p167 +set op2 = 0b101 in { + def FBPA : F2_3<0b1000, "fbpa">; // Branch always + def FBPN : F2_3<0b0000, "fbpn">; // Branch never + def FBPU : F2_3<0b0111, "fbpu">; // Branch on unordered + def FBPG : F2_3<0b0110, "fbpg">; // Branch > + def FBPUG : F2_3<0b0101, "fbpug">; // Branch on unordered or > + def FBPL : F2_3<0b0100, "fbpl">; // Branch < + def FBPUL : F2_3<0b0011, "fbpul">; // Branch on unordered or < + def FBPLG : F2_3<0b0010, "fbplg">; // Branch < or > + def FBPNE : F2_3<0b0001, "fbpne">; // Branch != + def FBPE : F2_3<0b1001, "fbpe">; // Branch == + def FBPUE : F2_3<0b1010, "fbpue">; // Branch on unordered or == + def FBPGE : F2_3<0b1011, "fbpge">; // Branch > or == + def FBPUGE : F2_3<0b1100, "fbpuge">; // Branch unord or > or == + def FBPLE : F2_3<0b1101, "fbple">; // Branch < or == + def FBPULE : F2_3<0b1110, "fbpule">; // Branch unord or < or == + def FBPO : F2_3<0b1111, "fbpo">; // Branch on ordered +} + +// Section A.6: p170: Bicc +set isDeprecated = 1 in { + set op2 = 0b010 in { + def BA : F2_2<0b1000, "ba">; // Branch always + def BN : F2_2<0b0000, "bn">; // Branch never + def BNE : F2_2<0b1001, "bne">; // Branch != + def BE : F2_2<0b0001, "be">; // Branch == + def BG : F2_2<0b1010, "bg">; // Branch > + def BLE : F2_2<0b0010, "ble">; // Branch <= + def BGE : F2_2<0b1011, "bge">; // Branch >= + def BL : F2_2<0b0011, "bl">; // Branch < + def BGU : F2_2<0b1100, "bgu">; // Branch unsigned > + def BLEU : F2_2<0b0100, "bleu">; // Branch unsigned <= + def BCC : F2_2<0b1101, "bcc">; // Branch unsigned >= + def BCS : F2_2<0b0101, "bcs">; // Branch unsigned <= + def BPOS : F2_2<0b1110, "bpos">; // Branch on positive + def BNEG : F2_2<0b0110, "bneg">; // Branch on negative + def BVC : F2_2<0b1111, "bvc">; // Branch on overflow clear + def BVS : F2_2<0b0111, "bvs">; // Branch on overflow set + } +} + +// Section A.7: p172 +set op2 = 0b001 in { + def BPA : F2_3<0b1000, "bpa">; // Branch always + def BPN : F2_3<0b0000, "bpn">; // Branch never + def BPNE : F2_3<0b1001, "bpne">; // Branch != + def BPE : F2_3<0b0001, "bpe">; // Branch == + def BPG : F2_3<0b1010, "bpg">; // Branch > + def BPLE : F2_3<0b0010, "bple">; // Branch <= + def BPGE : F2_3<0b1011, "bpge">; // Branch >= + def BPL : F2_3<0b0011, "bpl">; // Branch < + def BPGU : F2_3<0b1100, "bpgu">; // Branch unsigned > + + def BPLEU : F2_3<0b0100, "bpleu">; // Branch unsigned <= + def BPCC : F2_3<0b1101, "bpcc">; // Branch unsigned >= + def BPCS : F2_3<0b0101, "bpcs">; // Branch unsigned <= + def BPPOS : F2_3<0b1110, "bppos">; // Branch on positive + def BPNEG : F2_3<0b0110, "bpneg">; // Branch on negative + def BPVC : F2_3<0b1111, "bpvc">; // Branch on overflow clear + def BPVS : F2_3<0b0111, "bpvs">; // Branch on overflow set +} + +// Section A.8: p175 - CALL - the only Format #1 instruction +def CALL : InstV9 { + bits<30> disp; + set op = 1; + set Inst{29-0} = disp; + set Name = "call"; + set isCall = 1; +} + +// Section A.9: Compare and Swap - p176 +// CASA/CASXA: are for alternate address spaces! Ignore them + + +// Section A.10: Divide (64-bit / 32-bit) - p178 +set isDeprecated = 1 in { + def UDIVr : F3_1<2, 0b001110, "udiv">; // udiv r, r, r + def UDIVi : F3_2<2, 0b001110, "udiv">; // udiv r, r, i + def SDIVr : F3_1<2, 0b001111, "sdiv">; // sdiv r, r, r + def SDIVi : F3_2<2, 0b001111, "sdiv">; // sdiv r, r, i + def UDIVCCr : F3_1<2, 0b011110, "udivcc">; // udivcc r, r, r + def UDIVCCi : F3_2<2, 0b011110, "udivcc">; // udivcc r, r, i + def SDIVCCr : F3_1<2, 0b011111, "sdivcc">; // sdivcc r, r, r + def SDIVCCi : F3_2<2, 0b011111, "sdivcc">; // sdivcc r, r, i +} + +// Section A.11: DONE and RETRY - p181 +set isPrivileged = 1 in { + def DONE : F3_18<0, "done">; // done + def RETRY : F3_18<1, "retry">; // retry +} + +// Section A.12: Floating-Point Add and Subtract - p182 +def FADDS : F3_16<2, 0b110100, 0x41, "fadds">; // fadds f, f, f +def FADDD : F3_16<2, 0b110100, 0x42, "faddd">; // faddd f, f, f +def FADDQ : F3_16<2, 0b110100, 0x43, "faddq">; // faddq f, f, f +def FSUBS : F3_16<2, 0b110100, 0x45, "fsubs">; // fsubs f, f, f +def FSUBD : F3_16<2, 0b110100, 0x46, "fsubd">; // fsubd f, f, f +def FSUBQ : F3_16<2, 0b110100, 0x47, "fsubq">; // fsubq f, f, f + +// +// ... +// + +// Section A.45: RETURN - p240 +set isReturn = 1 in { + def RETURNr : F3_3<2, 0b111001, "return">; // return + def RETURNi : F3_4<2, 0b111001, "return">; // return +}