mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-26 20:57:15 +00:00
[SystemZ] Rename subregs and add subreg_h32
Use subreg_hNN and subreg_lNN for the high and low NN bits of a register. List the low registers first, so that subreg_l32 also means the low 32 bits of a 128-bit register. Floats are stored in the upper 32 bits of a 64-bit register, so they should use subreg_h32 rather than subreg_l32. No behavioral change intended. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191659 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
835e284214
commit
745ca1eed7
@ -111,7 +111,7 @@ static void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB,
|
||||
const SystemZTargetMachine &TM,
|
||||
unsigned GPR64, bool IsImplicit) {
|
||||
const SystemZRegisterInfo *RI = TM.getRegisterInfo();
|
||||
unsigned GPR32 = RI->getSubReg(GPR64, SystemZ::subreg_32bit);
|
||||
unsigned GPR32 = RI->getSubReg(GPR64, SystemZ::subreg_l32);
|
||||
bool IsLive = MBB.isLiveIn(GPR64) || MBB.isLiveIn(GPR32);
|
||||
if (!IsLive || !IsImplicit) {
|
||||
MIB.addReg(GPR64, getImplRegState(IsImplicit) | getKillRegState(!IsLive));
|
||||
|
@ -839,10 +839,10 @@ SDValue SystemZDAGToDAGISel::getUNDEF64(SDLoc DL) const {
|
||||
|
||||
SDValue SystemZDAGToDAGISel::convertTo(SDLoc DL, EVT VT, SDValue N) const {
|
||||
if (N.getValueType() == MVT::i32 && VT == MVT::i64)
|
||||
return CurDAG->getTargetInsertSubreg(SystemZ::subreg_32bit,
|
||||
return CurDAG->getTargetInsertSubreg(SystemZ::subreg_l32,
|
||||
DL, VT, getUNDEF64(DL), N);
|
||||
if (N.getValueType() == MVT::i64 && VT == MVT::i32)
|
||||
return CurDAG->getTargetExtractSubreg(SystemZ::subreg_32bit, DL, VT, N);
|
||||
return CurDAG->getTargetExtractSubreg(SystemZ::subreg_l32, DL, VT, N);
|
||||
assert(N.getValueType() == VT && "Unexpected value types");
|
||||
return N;
|
||||
}
|
||||
|
@ -1558,12 +1558,12 @@ SDValue SystemZTargetLowering::lowerBITCAST(SDValue Op,
|
||||
SDValue In64 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, In);
|
||||
SDValue Shift = DAG.getNode(ISD::SHL, DL, MVT::i64, In64, Shift32);
|
||||
SDValue Out64 = DAG.getNode(ISD::BITCAST, DL, MVT::f64, Shift);
|
||||
return DAG.getTargetExtractSubreg(SystemZ::subreg_32bit,
|
||||
return DAG.getTargetExtractSubreg(SystemZ::subreg_h32,
|
||||
DL, MVT::f32, Out64);
|
||||
}
|
||||
if (InVT == MVT::f32 && ResVT == MVT::i32) {
|
||||
SDNode *U64 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::f64);
|
||||
SDValue In64 = DAG.getTargetInsertSubreg(SystemZ::subreg_32bit, DL,
|
||||
SDValue In64 = DAG.getTargetInsertSubreg(SystemZ::subreg_h32, DL,
|
||||
MVT::f64, SDValue(U64, 0), In);
|
||||
SDValue Out64 = DAG.getNode(ISD::BITCAST, DL, MVT::i64, In64);
|
||||
SDValue Shift = DAG.getNode(ISD::SRL, DL, MVT::i64, Out64, Shift32);
|
||||
@ -1809,7 +1809,7 @@ SDValue SystemZTargetLowering::lowerOR(SDValue Op, SelectionDAG &DAG) const {
|
||||
// can be folded.
|
||||
SDLoc DL(Op);
|
||||
SDValue Low32 = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, LowOp);
|
||||
return DAG.getTargetInsertSubreg(SystemZ::subreg_32bit, DL,
|
||||
return DAG.getTargetInsertSubreg(SystemZ::subreg_l32, DL,
|
||||
MVT::i64, HighOp, Low32);
|
||||
}
|
||||
|
||||
@ -2602,8 +2602,8 @@ SystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr *MI,
|
||||
|
||||
// Emit an extension from a GR32 or GR64 to a GR128. ClearEven is true
|
||||
// if the high register of the GR128 value must be cleared or false if
|
||||
// it's "don't care". SubReg is subreg_odd32 when extending a GR32
|
||||
// and subreg_odd when extending a GR64.
|
||||
// it's "don't care". SubReg is subreg_l32 when extending a GR32
|
||||
// and subreg_l64 when extending a GR64.
|
||||
MachineBasicBlock *
|
||||
SystemZTargetLowering::emitExt128(MachineInstr *MI,
|
||||
MachineBasicBlock *MBB,
|
||||
@ -2625,7 +2625,7 @@ SystemZTargetLowering::emitExt128(MachineInstr *MI,
|
||||
BuildMI(*MBB, MI, DL, TII->get(SystemZ::LLILL), Zero64)
|
||||
.addImm(0);
|
||||
BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::INSERT_SUBREG), NewIn128)
|
||||
.addReg(In128).addReg(Zero64).addImm(SystemZ::subreg_high);
|
||||
.addReg(In128).addReg(Zero64).addImm(SystemZ::subreg_h64);
|
||||
In128 = NewIn128;
|
||||
}
|
||||
BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::INSERT_SUBREG), Dest)
|
||||
@ -2899,11 +2899,11 @@ EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const {
|
||||
return emitCondStore(MI, MBB, SystemZ::STD, 0, true);
|
||||
|
||||
case SystemZ::AEXT128_64:
|
||||
return emitExt128(MI, MBB, false, SystemZ::subreg_low);
|
||||
return emitExt128(MI, MBB, false, SystemZ::subreg_l64);
|
||||
case SystemZ::ZEXT128_32:
|
||||
return emitExt128(MI, MBB, true, SystemZ::subreg_low32);
|
||||
return emitExt128(MI, MBB, true, SystemZ::subreg_l32);
|
||||
case SystemZ::ZEXT128_64:
|
||||
return emitExt128(MI, MBB, true, SystemZ::subreg_low);
|
||||
return emitExt128(MI, MBB, true, SystemZ::subreg_l64);
|
||||
|
||||
case SystemZ::ATOMIC_SWAPW:
|
||||
return emitAtomicLoadBinary(MI, MBB, 0, 0);
|
||||
|
@ -62,7 +62,7 @@ let isCodeGenOnly = 1 in {
|
||||
|
||||
// The sign of an FP128 is in the high register.
|
||||
def : Pat<(fcopysign FP32:$src1, FP128:$src2),
|
||||
(CPSDRsd FP32:$src1, (EXTRACT_SUBREG FP128:$src2, subreg_high))>;
|
||||
(CPSDRsd FP32:$src1, (EXTRACT_SUBREG FP128:$src2, subreg_h64))>;
|
||||
|
||||
// fcopysign with an FP64 result.
|
||||
let isCodeGenOnly = 1 in
|
||||
@ -71,20 +71,20 @@ def CPSDRdd : BinaryRRF<"cpsd", 0xB372, fcopysign, FP64, FP64>;
|
||||
|
||||
// The sign of an FP128 is in the high register.
|
||||
def : Pat<(fcopysign FP64:$src1, FP128:$src2),
|
||||
(CPSDRdd FP64:$src1, (EXTRACT_SUBREG FP128:$src2, subreg_high))>;
|
||||
(CPSDRdd FP64:$src1, (EXTRACT_SUBREG FP128:$src2, subreg_h64))>;
|
||||
|
||||
// fcopysign with an FP128 result. Use "upper" as the high half and leave
|
||||
// the low half as-is.
|
||||
class CopySign128<RegisterOperand cls, dag upper>
|
||||
: Pat<(fcopysign FP128:$src1, cls:$src2),
|
||||
(INSERT_SUBREG FP128:$src1, upper, subreg_high)>;
|
||||
(INSERT_SUBREG FP128:$src1, upper, subreg_h64)>;
|
||||
|
||||
def : CopySign128<FP32, (CPSDRds (EXTRACT_SUBREG FP128:$src1, subreg_high),
|
||||
def : CopySign128<FP32, (CPSDRds (EXTRACT_SUBREG FP128:$src1, subreg_h64),
|
||||
FP32:$src2)>;
|
||||
def : CopySign128<FP64, (CPSDRdd (EXTRACT_SUBREG FP128:$src1, subreg_high),
|
||||
def : CopySign128<FP64, (CPSDRdd (EXTRACT_SUBREG FP128:$src1, subreg_h64),
|
||||
FP64:$src2)>;
|
||||
def : CopySign128<FP128, (CPSDRdd (EXTRACT_SUBREG FP128:$src1, subreg_high),
|
||||
(EXTRACT_SUBREG FP128:$src2, subreg_high))>;
|
||||
def : CopySign128<FP128, (CPSDRdd (EXTRACT_SUBREG FP128:$src1, subreg_h64),
|
||||
(EXTRACT_SUBREG FP128:$src2, subreg_h64))>;
|
||||
|
||||
defm LoadStoreF32 : MVCLoadStore<load, f32, MVCSequence, 4>;
|
||||
defm LoadStoreF64 : MVCLoadStore<load, f64, MVCSequence, 8>;
|
||||
@ -134,9 +134,9 @@ def LEXBR : UnaryRRE<"lexb", 0xB346, null_frag, FP128, FP128>;
|
||||
def LDXBR : UnaryRRE<"ldxb", 0xB345, null_frag, FP128, FP128>;
|
||||
|
||||
def : Pat<(f32 (fround FP128:$src)),
|
||||
(EXTRACT_SUBREG (LEXBR FP128:$src), subreg_32bit)>;
|
||||
(EXTRACT_SUBREG (LEXBR FP128:$src), subreg_hh32)>;
|
||||
def : Pat<(f64 (fround FP128:$src)),
|
||||
(EXTRACT_SUBREG (LDXBR FP128:$src), subreg_high)>;
|
||||
(EXTRACT_SUBREG (LDXBR FP128:$src), subreg_h64)>;
|
||||
|
||||
// Extend register floating-point values to wider representations.
|
||||
def LDEBR : UnaryRRE<"ldeb", 0xB304, fextend, FP64, FP32>;
|
||||
@ -300,26 +300,26 @@ def MDB : BinaryRXE<"mdb", 0xED1C, fmul, FP64, load, 8>;
|
||||
def MDEBR : BinaryRRE<"mdeb", 0xB30C, null_frag, FP64, FP32>;
|
||||
def : Pat<(fmul (f64 (fextend FP32:$src1)), (f64 (fextend FP32:$src2))),
|
||||
(MDEBR (INSERT_SUBREG (f64 (IMPLICIT_DEF)),
|
||||
FP32:$src1, subreg_32bit), FP32:$src2)>;
|
||||
FP32:$src1, subreg_h32), FP32:$src2)>;
|
||||
|
||||
// f64 multiplication of an FP32 register and an f32 memory.
|
||||
def MDEB : BinaryRXE<"mdeb", 0xED0C, null_frag, FP64, load, 4>;
|
||||
def : Pat<(fmul (f64 (fextend FP32:$src1)),
|
||||
(f64 (extloadf32 bdxaddr12only:$addr))),
|
||||
(MDEB (INSERT_SUBREG (f64 (IMPLICIT_DEF)), FP32:$src1, subreg_32bit),
|
||||
(MDEB (INSERT_SUBREG (f64 (IMPLICIT_DEF)), FP32:$src1, subreg_h32),
|
||||
bdxaddr12only:$addr)>;
|
||||
|
||||
// f128 multiplication of two FP64 registers.
|
||||
def MXDBR : BinaryRRE<"mxdb", 0xB307, null_frag, FP128, FP64>;
|
||||
def : Pat<(fmul (f128 (fextend FP64:$src1)), (f128 (fextend FP64:$src2))),
|
||||
(MXDBR (INSERT_SUBREG (f128 (IMPLICIT_DEF)),
|
||||
FP64:$src1, subreg_high), FP64:$src2)>;
|
||||
FP64:$src1, subreg_h64), FP64:$src2)>;
|
||||
|
||||
// f128 multiplication of an FP64 register and an f64 memory.
|
||||
def MXDB : BinaryRXE<"mxdb", 0xED07, null_frag, FP128, load, 8>;
|
||||
def : Pat<(fmul (f128 (fextend FP64:$src1)),
|
||||
(f128 (extloadf64 bdxaddr12only:$addr))),
|
||||
(MXDB (INSERT_SUBREG (f128 (IMPLICIT_DEF)), FP64:$src1, subreg_high),
|
||||
(MXDB (INSERT_SUBREG (f128 (IMPLICIT_DEF)), FP64:$src1, subreg_h64),
|
||||
bdxaddr12only:$addr)>;
|
||||
|
||||
// Fused multiply-add.
|
||||
|
@ -48,8 +48,8 @@ void SystemZInstrInfo::splitMove(MachineBasicBlock::iterator MI,
|
||||
// Set up the two 64-bit registers.
|
||||
MachineOperand &HighRegOp = EarlierMI->getOperand(0);
|
||||
MachineOperand &LowRegOp = MI->getOperand(0);
|
||||
HighRegOp.setReg(RI.getSubReg(HighRegOp.getReg(), SystemZ::subreg_high));
|
||||
LowRegOp.setReg(RI.getSubReg(LowRegOp.getReg(), SystemZ::subreg_low));
|
||||
HighRegOp.setReg(RI.getSubReg(HighRegOp.getReg(), SystemZ::subreg_h64));
|
||||
LowRegOp.setReg(RI.getSubReg(LowRegOp.getReg(), SystemZ::subreg_l64));
|
||||
|
||||
// The address in the first (high) instruction is already correct.
|
||||
// Adjust the offset in the second (low) instruction.
|
||||
@ -453,10 +453,10 @@ SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
bool KillSrc) const {
|
||||
// Split 128-bit GPR moves into two 64-bit moves. This handles ADDR128 too.
|
||||
if (SystemZ::GR128BitRegClass.contains(DestReg, SrcReg)) {
|
||||
copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_high),
|
||||
RI.getSubReg(SrcReg, SystemZ::subreg_high), KillSrc);
|
||||
copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_low),
|
||||
RI.getSubReg(SrcReg, SystemZ::subreg_low), KillSrc);
|
||||
copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_h64),
|
||||
RI.getSubReg(SrcReg, SystemZ::subreg_h64), KillSrc);
|
||||
copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_l64),
|
||||
RI.getSubReg(SrcReg, SystemZ::subreg_l64), KillSrc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -393,7 +393,7 @@ let Defs = [CC], CCValues = 0xE, CompareZeroCCMask = 0xE in
|
||||
// Match 32-to-64-bit sign extensions in which the source is already
|
||||
// in a 64-bit register.
|
||||
def : Pat<(sext_inreg GR64:$src, i32),
|
||||
(LGFR (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;
|
||||
(LGFR (EXTRACT_SUBREG GR64:$src, subreg_l32))>;
|
||||
|
||||
// 32-bit extensions from memory.
|
||||
def LB : UnaryRXY<"lb", 0xE376, asextloadi8, GR32, 1>;
|
||||
@ -429,7 +429,7 @@ let neverHasSideEffects = 1 in {
|
||||
// Match 32-to-64-bit zero extensions in which the source is already
|
||||
// in a 64-bit register.
|
||||
def : Pat<(and GR64:$src, 0xffffffff),
|
||||
(LLGFR (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;
|
||||
(LLGFR (EXTRACT_SUBREG GR64:$src, subreg_l32))>;
|
||||
|
||||
// 32-bit extensions from memory.
|
||||
def LLC : UnaryRXY<"llc", 0xE394, azextloadi8, GR32, 1>;
|
||||
@ -449,7 +449,7 @@ def LLGFRL : UnaryRILPC<"llgfrl", 0xC4E, aligned_azextloadi32, GR64>;
|
||||
|
||||
// Truncations of 64-bit registers to 32-bit registers.
|
||||
def : Pat<(i32 (trunc GR64:$src)),
|
||||
(EXTRACT_SUBREG GR64:$src, subreg_32bit)>;
|
||||
(EXTRACT_SUBREG GR64:$src, subreg_l32)>;
|
||||
|
||||
// Truncations of 32-bit registers to memory.
|
||||
defm STC : StoreRXPair<"stc", 0x42, 0xE372, truncstorei8, GR32, 1>;
|
||||
@ -589,7 +589,7 @@ def IIHF : BinaryRIL<"iihf", 0xC08, inserthf, GR64, imm64hf32>;
|
||||
// An alternative model of inserthf, with the first operand being
|
||||
// a zero-extended value.
|
||||
def : Pat<(or (zext32 GR32:$src), imm64hf32:$imm),
|
||||
(IIHF (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit),
|
||||
(IIHF (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_l32),
|
||||
imm64hf32:$imm)>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1184,11 +1184,11 @@ let Defs = [CC] in {
|
||||
def FLOGR : UnaryRRE<"flog", 0xB983, null_frag, GR128, GR64>;
|
||||
}
|
||||
def : Pat<(ctlz GR64:$src),
|
||||
(EXTRACT_SUBREG (FLOGR GR64:$src), subreg_high)>;
|
||||
(EXTRACT_SUBREG (FLOGR GR64:$src), subreg_h64)>;
|
||||
|
||||
// Use subregs to populate the "don't care" bits in a 32-bit to 64-bit anyext.
|
||||
def : Pat<(i64 (anyext GR32:$src)),
|
||||
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>;
|
||||
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_l32)>;
|
||||
|
||||
// Extend GR32s and GR64s to GR128s.
|
||||
let usesCustomInserter = 1 in {
|
||||
|
@ -13,7 +13,7 @@ multiclass SXU<SDPatternOperator operator, Instruction insn> {
|
||||
def : Pat<(operator (sext (i32 GR32:$src))),
|
||||
(insn GR32:$src)>;
|
||||
def : Pat<(operator (sext_inreg GR64:$src, i32)),
|
||||
(insn (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;
|
||||
(insn (EXTRACT_SUBREG GR64:$src, subreg_l32))>;
|
||||
}
|
||||
|
||||
// Record that INSN performs a 64-bit version of binary operator OPERATOR
|
||||
@ -24,7 +24,7 @@ multiclass SXB<SDPatternOperator operator, RegisterOperand cls,
|
||||
def : Pat<(operator cls:$src1, (sext GR32:$src2)),
|
||||
(insn cls:$src1, GR32:$src2)>;
|
||||
def : Pat<(operator cls:$src1, (sext_inreg GR64:$src2, i32)),
|
||||
(insn cls:$src1, (EXTRACT_SUBREG GR64:$src2, subreg_32bit))>;
|
||||
(insn cls:$src1, (EXTRACT_SUBREG GR64:$src2, subreg_l32))>;
|
||||
}
|
||||
|
||||
// Like SXB, but for zero extension.
|
||||
@ -33,7 +33,7 @@ multiclass ZXB<SDPatternOperator operator, RegisterOperand cls,
|
||||
def : Pat<(operator cls:$src1, (zext GR32:$src2)),
|
||||
(insn cls:$src1, GR32:$src2)>;
|
||||
def : Pat<(operator cls:$src1, (and GR64:$src2, 0xffffffff)),
|
||||
(insn cls:$src1, (EXTRACT_SUBREG GR64:$src2, subreg_32bit))>;
|
||||
(insn cls:$src1, (EXTRACT_SUBREG GR64:$src2, subreg_l32))>;
|
||||
}
|
||||
|
||||
// Record that INSN performs a binary read-modify-write operation,
|
||||
@ -71,7 +71,7 @@ multiclass InsertMem<string type, Instruction insn, RegisterOperand cls,
|
||||
class StoreGR64<Instruction insn, SDPatternOperator operator,
|
||||
AddressingMode mode>
|
||||
: Pat<(operator GR64:$R1, mode:$XBD2),
|
||||
(insn (EXTRACT_SUBREG GR64:$R1, subreg_32bit), mode:$XBD2)>;
|
||||
(insn (EXTRACT_SUBREG GR64:$R1, subreg_l32), mode:$XBD2)>;
|
||||
|
||||
// INSN and INSNY are an RX/RXY pair of instructions that store the low
|
||||
// 32 bits of a GPR to memory. Record that they are equivalent to using
|
||||
@ -86,7 +86,7 @@ multiclass StoreGR64Pair<Instruction insn, Instruction insny,
|
||||
// Record that it is equivalent to using OPERATOR to store a GR64.
|
||||
class StoreGR64PC<Instruction insn, SDPatternOperator operator>
|
||||
: Pat<(operator GR64:$R1, pcrel32:$XBD2),
|
||||
(insn (EXTRACT_SUBREG GR64:$R1, subreg_32bit), pcrel32:$XBD2)> {
|
||||
(insn (EXTRACT_SUBREG GR64:$R1, subreg_l32), pcrel32:$XBD2)> {
|
||||
// We want PC-relative addresses to be tried ahead of BD and BDX addresses.
|
||||
// However, BDXs have two extra operands and are therefore 6 units more
|
||||
// complex.
|
||||
@ -103,12 +103,12 @@ multiclass CondStores64<Instruction insn, Instruction insninv,
|
||||
def : Pat<(store (z_select_ccmask GR64:$new, (load mode:$addr),
|
||||
uimm8zx4:$valid, uimm8zx4:$cc),
|
||||
mode:$addr),
|
||||
(insn (EXTRACT_SUBREG GR64:$new, subreg_32bit), mode:$addr,
|
||||
(insn (EXTRACT_SUBREG GR64:$new, subreg_l32), mode:$addr,
|
||||
uimm8zx4:$valid, uimm8zx4:$cc)>;
|
||||
def : Pat<(store (z_select_ccmask (load mode:$addr), GR64:$new,
|
||||
uimm8zx4:$valid, uimm8zx4:$cc),
|
||||
mode:$addr),
|
||||
(insninv (EXTRACT_SUBREG GR64:$new, subreg_32bit), mode:$addr,
|
||||
(insninv (EXTRACT_SUBREG GR64:$new, subreg_l32), mode:$addr,
|
||||
uimm8zx4:$valid, uimm8zx4:$cc)>;
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ multiclass CondStores64<Instruction insn, Instruction insninv,
|
||||
class CompareGR64RI<Instruction insn, SDPatternOperator compare,
|
||||
Immediate imm>
|
||||
: Pat<(compare GR64:$R1, imm:$I2),
|
||||
(insn (EXTRACT_SUBREG GR64:$R1, subreg_32bit),
|
||||
(insn (EXTRACT_SUBREG GR64:$R1, subreg_l32),
|
||||
(imm.OperandTransform imm:$I2))>;
|
||||
|
||||
// Try to use MVC instruction INSN for a load of type LOAD followed by a store
|
||||
|
@ -22,10 +22,10 @@ namespace SystemZ {
|
||||
// Return the subreg to use for referring to the even and odd registers
|
||||
// in a GR128 pair. Is32Bit says whether we want a GR32 or GR64.
|
||||
inline unsigned even128(bool Is32bit) {
|
||||
return Is32bit ? subreg_32bit : subreg_high;
|
||||
return Is32bit ? subreg_hl32 : subreg_h64;
|
||||
}
|
||||
inline unsigned odd128(bool Is32bit) {
|
||||
return Is32bit ? subreg_low32 : subreg_low;
|
||||
return Is32bit ? subreg_l32 : subreg_l64;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,12 @@ class SystemZRegWithSubregs<string n, list<Register> subregs>
|
||||
}
|
||||
|
||||
let Namespace = "SystemZ" in {
|
||||
def subreg_32bit : SubRegIndex<32>; // could also be named "subreg_high32"
|
||||
// Indices are used in a variety of ways, so don't set an Offset.
|
||||
def subreg_high : SubRegIndex<64, -1>;
|
||||
def subreg_low : SubRegIndex<64, -1>;
|
||||
def subreg_low32 : ComposedSubRegIndex<subreg_low, subreg_32bit>;
|
||||
def subreg_l32 : SubRegIndex<32, 0>; // Also acts as subreg_ll32.
|
||||
def subreg_h32 : SubRegIndex<32, 32>; // Also acts as subreg_lh32.
|
||||
def subreg_l64 : SubRegIndex<64, 0>;
|
||||
def subreg_h64 : SubRegIndex<64, 64>;
|
||||
def subreg_hh32 : ComposedSubRegIndex<subreg_h64, subreg_h32>;
|
||||
def subreg_hl32 : ComposedSubRegIndex<subreg_h64, subreg_l32>;
|
||||
}
|
||||
|
||||
// Define a register class that contains values of type TYPE and an
|
||||
@ -58,14 +59,14 @@ class GPR32<bits<16> num, string n> : SystemZReg<n> {
|
||||
class GPR64<bits<16> num, string n, GPR32 low>
|
||||
: SystemZRegWithSubregs<n, [low]> {
|
||||
let HWEncoding = num;
|
||||
let SubRegIndices = [subreg_32bit];
|
||||
let SubRegIndices = [subreg_l32];
|
||||
}
|
||||
|
||||
// 8 even-odd pairs of GPR64s.
|
||||
class GPR128<bits<16> num, string n, GPR64 high, GPR64 low>
|
||||
: SystemZRegWithSubregs<n, [high, low]> {
|
||||
let HWEncoding = num;
|
||||
let SubRegIndices = [subreg_high, subreg_low];
|
||||
let SubRegIndices = [subreg_l64, subreg_h64];
|
||||
}
|
||||
|
||||
// General-purpose registers
|
||||
@ -75,8 +76,8 @@ foreach I = 0-15 in {
|
||||
}
|
||||
|
||||
foreach I = [0, 2, 4, 6, 8, 10, 12, 14] in {
|
||||
def R#I#Q : GPR128<I, "r"#I, !cast<GPR64>("R"#I#"D"),
|
||||
!cast<GPR64>("R"#!add(I, 1)#"D")>;
|
||||
def R#I#Q : GPR128<I, "r"#I, !cast<GPR64>("R"#!add(I, 1)#"D"),
|
||||
!cast<GPR64>("R"#I#"D")>;
|
||||
}
|
||||
|
||||
/// Allocate the callee-saved R6-R13 backwards. That way they can be saved
|
||||
@ -114,14 +115,14 @@ class FPR32<bits<16> num, string n> : SystemZReg<n> {
|
||||
class FPR64<bits<16> num, string n, FPR32 low>
|
||||
: SystemZRegWithSubregs<n, [low]> {
|
||||
let HWEncoding = num;
|
||||
let SubRegIndices = [subreg_32bit];
|
||||
let SubRegIndices = [subreg_h32];
|
||||
}
|
||||
|
||||
// 8 pairs of FPR64s, with a one-register gap inbetween.
|
||||
class FPR128<bits<16> num, string n, FPR64 high, FPR64 low>
|
||||
: SystemZRegWithSubregs<n, [high, low]> {
|
||||
let HWEncoding = num;
|
||||
let SubRegIndices = [subreg_high, subreg_low];
|
||||
let SubRegIndices = [subreg_l64, subreg_h64];
|
||||
}
|
||||
|
||||
// Floating-point registers
|
||||
@ -132,8 +133,8 @@ foreach I = 0-15 in {
|
||||
}
|
||||
|
||||
foreach I = [0, 1, 4, 5, 8, 9, 12, 13] in {
|
||||
def F#I#Q : FPR128<I, "f"#I, !cast<FPR64>("F"#I#"D"),
|
||||
!cast<FPR64>("F"#!add(I, 2)#"D")>;
|
||||
def F#I#Q : FPR128<I, "f"#I, !cast<FPR64>("F"#!add(I, 2)#"D"),
|
||||
!cast<FPR64>("F"#I#"D")>;
|
||||
}
|
||||
|
||||
// There's no store-multiple instruction for FPRs, so we're not fussy
|
||||
|
Loading…
x
Reference in New Issue
Block a user