mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-03 13:31:05 +00:00
Remove aligned/unaligned load/store fragments defined in MipsInstrInfo.td and
use load/store fragments defined in TargetSelectionDAG.td in place of them. Unaligned loads/stores are either expanded or lowered to target-specific nodes, so instruction selection should see only aligned load/store nodes. No changes in functionality. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163960 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5974c31acb
commit
5a7dd43f04
@ -403,16 +403,16 @@ class LoadM16_pat<PatFrag OpNode, Instruction I> :
|
||||
|
||||
def: LoadM16_pat<sextloadi8, LbRxRyOffMemX16>;
|
||||
def: LoadM16_pat<zextloadi8, LbuRxRyOffMemX16>;
|
||||
def: LoadM16_pat<sextloadi16_a, LhRxRyOffMemX16>;
|
||||
def: LoadM16_pat<zextloadi16_a, LhuRxRyOffMemX16>;
|
||||
def: LoadM16_pat<load_a, LwRxRyOffMemX16>;
|
||||
def: LoadM16_pat<sextloadi16, LhRxRyOffMemX16>;
|
||||
def: LoadM16_pat<zextloadi16, LhuRxRyOffMemX16>;
|
||||
def: LoadM16_pat<load, LwRxRyOffMemX16>;
|
||||
|
||||
class StoreM16_pat<PatFrag OpNode, Instruction I> :
|
||||
Mips16Pat<(OpNode CPU16Regs:$r, addr:$addr), (I CPU16Regs:$r, addr:$addr)>;
|
||||
|
||||
def: StoreM16_pat<truncstorei8, SbRxRyOffMemX16>;
|
||||
def: StoreM16_pat<truncstorei16_a, ShRxRyOffMemX16>;
|
||||
def: StoreM16_pat<store_a, SwRxRyOffMemX16>;
|
||||
def: StoreM16_pat<truncstorei16, ShRxRyOffMemX16>;
|
||||
def: StoreM16_pat<store, SwRxRyOffMemX16>;
|
||||
|
||||
|
||||
// Jump and Link (Call)
|
||||
|
@ -127,24 +127,15 @@ let DecoderNamespace = "Mips64" in {
|
||||
/// aligned
|
||||
defm LB64 : LoadM64<0x20, "lb", sextloadi8>;
|
||||
defm LBu64 : LoadM64<0x24, "lbu", zextloadi8>;
|
||||
defm LH64 : LoadM64<0x21, "lh", sextloadi16_a>;
|
||||
defm LHu64 : LoadM64<0x25, "lhu", zextloadi16_a>;
|
||||
defm LW64 : LoadM64<0x23, "lw", sextloadi32_a>;
|
||||
defm LWu64 : LoadM64<0x27, "lwu", zextloadi32_a>;
|
||||
defm LH64 : LoadM64<0x21, "lh", sextloadi16>;
|
||||
defm LHu64 : LoadM64<0x25, "lhu", zextloadi16>;
|
||||
defm LW64 : LoadM64<0x23, "lw", sextloadi32>;
|
||||
defm LWu64 : LoadM64<0x27, "lwu", zextloadi32>;
|
||||
defm SB64 : StoreM64<0x28, "sb", truncstorei8>;
|
||||
defm SH64 : StoreM64<0x29, "sh", truncstorei16_a>;
|
||||
defm SW64 : StoreM64<0x2b, "sw", truncstorei32_a>;
|
||||
defm LD : LoadM64<0x37, "ld", load_a>;
|
||||
defm SD : StoreM64<0x3f, "sd", store_a>;
|
||||
|
||||
/// unaligned
|
||||
defm ULH64 : LoadM64<0x21, "ulh", sextloadi16_u, 1>;
|
||||
defm ULHu64 : LoadM64<0x25, "ulhu", zextloadi16_u, 1>;
|
||||
defm ULW64 : LoadM64<0x23, "ulw", sextloadi32_u, 1>;
|
||||
defm USH64 : StoreM64<0x29, "ush", truncstorei16_u, 1>;
|
||||
defm USW64 : StoreM64<0x2b, "usw", truncstorei32_u, 1>;
|
||||
defm ULD : LoadM64<0x37, "uld", load_u, 1>;
|
||||
defm USD : StoreM64<0x3f, "usd", store_u, 1>;
|
||||
defm SH64 : StoreM64<0x29, "sh", truncstorei16>;
|
||||
defm SW64 : StoreM64<0x2b, "sw", truncstorei32>;
|
||||
defm LD : LoadM64<0x37, "ld", load>;
|
||||
defm SD : StoreM64<0x3f, "sd", store>;
|
||||
|
||||
/// load/store left/right
|
||||
let isCodeGenOnly = 1 in {
|
||||
@ -244,21 +235,14 @@ let isCodeGenOnly = 1, rs = 0, shamt = 0 in {
|
||||
let Predicates = [NotN64, HasStandardEncoding] in {
|
||||
def : MipsPat<(i64 (extloadi1 addr:$src)), (LB64 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi8 addr:$src)), (LB64 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi16_a addr:$src)), (LH64 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi16_u addr:$src)), (ULH64 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi32_a addr:$src)), (LW64 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi32_u addr:$src)), (ULW64 addr:$src)>;
|
||||
def : MipsPat<(zextloadi32_u addr:$a), (DSRL (DSLL (ULW64 addr:$a), 32), 32)>;
|
||||
def : MipsPat<(i64 (extloadi16 addr:$src)), (LH64 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi32 addr:$src)), (LW64 addr:$src)>;
|
||||
}
|
||||
let Predicates = [IsN64, HasStandardEncoding] in {
|
||||
def : MipsPat<(i64 (extloadi1 addr:$src)), (LB64_P8 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi8 addr:$src)), (LB64_P8 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi16_a addr:$src)), (LH64_P8 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi16_u addr:$src)), (ULH64_P8 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi32_a addr:$src)), (LW64_P8 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi32_u addr:$src)), (ULW64_P8 addr:$src)>;
|
||||
def : MipsPat<(zextloadi32_u addr:$a),
|
||||
(DSRL (DSLL (ULW64_P8 addr:$a), 32), 32)>;
|
||||
def : MipsPat<(i64 (extloadi16 addr:$src)), (LH64_P8 addr:$src)>;
|
||||
def : MipsPat<(i64 (extloadi32 addr:$src)), (LW64_P8 addr:$src)>;
|
||||
}
|
||||
|
||||
// hi/lo relocs
|
||||
|
@ -218,15 +218,9 @@ unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
|
||||
return getMipsRegisterNumbering(MO.getReg());
|
||||
else if (MO.isImm())
|
||||
return static_cast<unsigned>(MO.getImm());
|
||||
else if (MO.isGlobal()) {
|
||||
if (MI.getOpcode() == Mips::ULW || MI.getOpcode() == Mips::USW ||
|
||||
MI.getOpcode() == Mips::ULH || MI.getOpcode() == Mips::ULHu)
|
||||
emitGlobalAddressUnaligned(MO.getGlobal(), getRelocation(MI, MO), 4);
|
||||
else if (MI.getOpcode() == Mips::USH)
|
||||
emitGlobalAddressUnaligned(MO.getGlobal(), getRelocation(MI, MO), 8);
|
||||
else
|
||||
emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
|
||||
} else if (MO.isSymbol())
|
||||
else if (MO.isGlobal())
|
||||
emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
|
||||
else if (MO.isSymbol())
|
||||
emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
|
||||
else if (MO.isCPI())
|
||||
emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
|
||||
@ -383,29 +377,8 @@ void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {
|
||||
if ((MI.getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo)
|
||||
return;
|
||||
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
case Mips::USW:
|
||||
NumEmitted += emitUSW(MI);
|
||||
break;
|
||||
case Mips::ULW:
|
||||
NumEmitted += emitULW(MI);
|
||||
break;
|
||||
case Mips::ULH:
|
||||
NumEmitted += emitULH(MI);
|
||||
break;
|
||||
case Mips::ULHu:
|
||||
NumEmitted += emitULHu(MI);
|
||||
break;
|
||||
case Mips::USH:
|
||||
NumEmitted += emitUSH(MI);
|
||||
break;
|
||||
|
||||
default:
|
||||
emitWordLE(getBinaryCodeForInstr(MI));
|
||||
++NumEmitted; // Keep track of the # of mi's emitted
|
||||
break;
|
||||
}
|
||||
emitWordLE(getBinaryCodeForInstr(MI));
|
||||
++NumEmitted; // Keep track of the # of mi's emitted
|
||||
|
||||
MCE.processDebugLoc(MI.getDebugLoc(), false);
|
||||
}
|
||||
|
@ -540,6 +540,15 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
|
||||
return RegOpnd;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
case ISD::LOAD:
|
||||
case ISD::STORE:
|
||||
assert(cast<MemSDNode>(Node)->getMemoryVT().getSizeInBits() / 8 <=
|
||||
cast<MemSDNode>(Node)->getAlignment() &&
|
||||
"Unexpected unaligned loads/stores.");
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MipsISD::ThreadPointer: {
|
||||
EVT PtrVT = TLI.getPointerTy();
|
||||
unsigned RdhwrOpc, SrcReg, DestReg;
|
||||
|
@ -90,13 +90,13 @@ def fpimm0neg : PatLeaf<(fpimm), [{
|
||||
let DecoderMethod = "DecodeFMem" in {
|
||||
class FPLoad<bits<6> op, string opstr, RegisterClass RC, Operand MemOpnd>:
|
||||
FMem<op, (outs RC:$ft), (ins MemOpnd:$addr),
|
||||
!strconcat(opstr, "\t$ft, $addr"), [(set RC:$ft, (load_a addr:$addr))],
|
||||
!strconcat(opstr, "\t$ft, $addr"), [(set RC:$ft, (load addr:$addr))],
|
||||
IILoad>;
|
||||
|
||||
// FP store.
|
||||
class FPStore<bits<6> op, string opstr, RegisterClass RC, Operand MemOpnd>:
|
||||
FMem<op, (outs), (ins RC:$ft, MemOpnd:$addr),
|
||||
!strconcat(opstr, "\t$ft, $addr"), [(store_a RC:$ft, addr:$addr)],
|
||||
!strconcat(opstr, "\t$ft, $addr"), [(store RC:$ft, addr:$addr)],
|
||||
IIStore>;
|
||||
}
|
||||
// FP indexed load.
|
||||
@ -282,26 +282,26 @@ let Predicates = [NotN64, NotMips64, HasStandardEncoding] in {
|
||||
|
||||
// Indexed loads and stores.
|
||||
let Predicates = [HasMips32r2Or64, HasStandardEncoding] in {
|
||||
def LWXC1 : FPIdxLoad<0x0, "lwxc1", FGR32, CPURegs, load_a>;
|
||||
def SWXC1 : FPIdxStore<0x8, "swxc1", FGR32, CPURegs, store_a>;
|
||||
def LWXC1 : FPIdxLoad<0x0, "lwxc1", FGR32, CPURegs, load>;
|
||||
def SWXC1 : FPIdxStore<0x8, "swxc1", FGR32, CPURegs, store>;
|
||||
}
|
||||
|
||||
let Predicates = [HasMips32r2, NotMips64, HasStandardEncoding] in {
|
||||
def LDXC1 : FPIdxLoad<0x1, "ldxc1", AFGR64, CPURegs, load_a>;
|
||||
def SDXC1 : FPIdxStore<0x9, "sdxc1", AFGR64, CPURegs, store_a>;
|
||||
def LDXC1 : FPIdxLoad<0x1, "ldxc1", AFGR64, CPURegs, load>;
|
||||
def SDXC1 : FPIdxStore<0x9, "sdxc1", AFGR64, CPURegs, store>;
|
||||
}
|
||||
|
||||
let Predicates = [HasMips64, NotN64, HasStandardEncoding], DecoderNamespace="Mips64" in {
|
||||
def LDXC164 : FPIdxLoad<0x1, "ldxc1", FGR64, CPURegs, load_a>;
|
||||
def SDXC164 : FPIdxStore<0x9, "sdxc1", FGR64, CPURegs, store_a>;
|
||||
def LDXC164 : FPIdxLoad<0x1, "ldxc1", FGR64, CPURegs, load>;
|
||||
def SDXC164 : FPIdxStore<0x9, "sdxc1", FGR64, CPURegs, store>;
|
||||
}
|
||||
|
||||
// n64
|
||||
let Predicates = [IsN64, HasStandardEncoding], isCodeGenOnly=1 in {
|
||||
def LWXC1_P8 : FPIdxLoad<0x0, "lwxc1", FGR32, CPU64Regs, load_a>;
|
||||
def LDXC164_P8 : FPIdxLoad<0x1, "ldxc1", FGR64, CPU64Regs, load_a>;
|
||||
def SWXC1_P8 : FPIdxStore<0x8, "swxc1", FGR32, CPU64Regs, store_a>;
|
||||
def SDXC164_P8 : FPIdxStore<0x9, "sdxc1", FGR64, CPU64Regs, store_a>;
|
||||
def LWXC1_P8 : FPIdxLoad<0x0, "lwxc1", FGR32, CPU64Regs, load>;
|
||||
def LDXC164_P8 : FPIdxLoad<0x1, "ldxc1", FGR64, CPU64Regs, load>;
|
||||
def SWXC1_P8 : FPIdxStore<0x8, "swxc1", FGR32, CPU64Regs, store>;
|
||||
def SDXC164_P8 : FPIdxStore<0x9, "sdxc1", FGR64, CPU64Regs, store>;
|
||||
}
|
||||
|
||||
// Load/store doubleword indexed unaligned.
|
||||
|
@ -292,55 +292,6 @@ def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
|
||||
def addr :
|
||||
ComplexPattern<iPTR, 2, "SelectAddr", [frameindex], [SDNPWantParent]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pattern fragment for load/store
|
||||
//===----------------------------------------------------------------------===//
|
||||
class UnalignedLoad<PatFrag Node> :
|
||||
PatFrag<(ops node:$ptr), (Node node:$ptr), [{
|
||||
LoadSDNode *LD = cast<LoadSDNode>(N);
|
||||
return LD->getMemoryVT().getSizeInBits()/8 > LD->getAlignment();
|
||||
}]>;
|
||||
|
||||
class AlignedLoad<PatFrag Node> :
|
||||
PatFrag<(ops node:$ptr), (Node node:$ptr), [{
|
||||
LoadSDNode *LD = cast<LoadSDNode>(N);
|
||||
return LD->getMemoryVT().getSizeInBits()/8 <= LD->getAlignment();
|
||||
}]>;
|
||||
|
||||
class UnalignedStore<PatFrag Node> :
|
||||
PatFrag<(ops node:$val, node:$ptr), (Node node:$val, node:$ptr), [{
|
||||
StoreSDNode *SD = cast<StoreSDNode>(N);
|
||||
return SD->getMemoryVT().getSizeInBits()/8 > SD->getAlignment();
|
||||
}]>;
|
||||
|
||||
class AlignedStore<PatFrag Node> :
|
||||
PatFrag<(ops node:$val, node:$ptr), (Node node:$val, node:$ptr), [{
|
||||
StoreSDNode *SD = cast<StoreSDNode>(N);
|
||||
return SD->getMemoryVT().getSizeInBits()/8 <= SD->getAlignment();
|
||||
}]>;
|
||||
|
||||
// Load/Store PatFrags.
|
||||
def sextloadi16_a : AlignedLoad<sextloadi16>;
|
||||
def zextloadi16_a : AlignedLoad<zextloadi16>;
|
||||
def extloadi16_a : AlignedLoad<extloadi16>;
|
||||
def load_a : AlignedLoad<load>;
|
||||
def sextloadi32_a : AlignedLoad<sextloadi32>;
|
||||
def zextloadi32_a : AlignedLoad<zextloadi32>;
|
||||
def extloadi32_a : AlignedLoad<extloadi32>;
|
||||
def truncstorei16_a : AlignedStore<truncstorei16>;
|
||||
def store_a : AlignedStore<store>;
|
||||
def truncstorei32_a : AlignedStore<truncstorei32>;
|
||||
def sextloadi16_u : UnalignedLoad<sextloadi16>;
|
||||
def zextloadi16_u : UnalignedLoad<zextloadi16>;
|
||||
def extloadi16_u : UnalignedLoad<extloadi16>;
|
||||
def load_u : UnalignedLoad<load>;
|
||||
def sextloadi32_u : UnalignedLoad<sextloadi32>;
|
||||
def zextloadi32_u : UnalignedLoad<zextloadi32>;
|
||||
def extloadi32_u : UnalignedLoad<extloadi32>;
|
||||
def truncstorei16_u : UnalignedStore<truncstorei16>;
|
||||
def store_u : UnalignedStore<store>;
|
||||
def truncstorei32_u : UnalignedStore<truncstorei32>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions specific format
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -957,19 +908,12 @@ let Predicates = [HasMips32r2, HasStandardEncoding] in {
|
||||
/// aligned
|
||||
defm LB : LoadM32<0x20, "lb", sextloadi8>;
|
||||
defm LBu : LoadM32<0x24, "lbu", zextloadi8>;
|
||||
defm LH : LoadM32<0x21, "lh", sextloadi16_a>;
|
||||
defm LHu : LoadM32<0x25, "lhu", zextloadi16_a>;
|
||||
defm LW : LoadM32<0x23, "lw", load_a>;
|
||||
defm LH : LoadM32<0x21, "lh", sextloadi16>;
|
||||
defm LHu : LoadM32<0x25, "lhu", zextloadi16>;
|
||||
defm LW : LoadM32<0x23, "lw", load>;
|
||||
defm SB : StoreM32<0x28, "sb", truncstorei8>;
|
||||
defm SH : StoreM32<0x29, "sh", truncstorei16_a>;
|
||||
defm SW : StoreM32<0x2b, "sw", store_a>;
|
||||
|
||||
/// unaligned
|
||||
defm ULH : LoadM32<0x21, "ulh", sextloadi16_u, 1>;
|
||||
defm ULHu : LoadM32<0x25, "ulhu", zextloadi16_u, 1>;
|
||||
defm ULW : LoadM32<0x23, "ulw", load_u, 1>;
|
||||
defm USH : StoreM32<0x29, "ush", truncstorei16_u, 1>;
|
||||
defm USW : StoreM32<0x2b, "usw", store_u, 1>;
|
||||
defm SH : StoreM32<0x29, "sh", truncstorei16>;
|
||||
defm SW : StoreM32<0x2b, "sw", store>;
|
||||
|
||||
/// load/store left/right
|
||||
defm LWL : LoadLeftRightM32<0x22, "lwl", MipsLWL>;
|
||||
@ -1181,24 +1125,20 @@ def : MipsPat<(not CPURegs:$in),
|
||||
let Predicates = [NotN64, HasStandardEncoding] in {
|
||||
def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
|
||||
def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
|
||||
def : MipsPat<(i32 (extloadi16_a addr:$src)), (LHu addr:$src)>;
|
||||
def : MipsPat<(i32 (extloadi16_u addr:$src)), (ULHu addr:$src)>;
|
||||
def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
|
||||
}
|
||||
let Predicates = [IsN64, HasStandardEncoding] in {
|
||||
def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu_P8 addr:$src)>;
|
||||
def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu_P8 addr:$src)>;
|
||||
def : MipsPat<(i32 (extloadi16_a addr:$src)), (LHu_P8 addr:$src)>;
|
||||
def : MipsPat<(i32 (extloadi16_u addr:$src)), (ULHu_P8 addr:$src)>;
|
||||
def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu_P8 addr:$src)>;
|
||||
}
|
||||
|
||||
// peepholes
|
||||
let Predicates = [NotN64, HasStandardEncoding] in {
|
||||
def : MipsPat<(store_a (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
|
||||
def : MipsPat<(store_u (i32 0), addr:$dst), (USW ZERO, addr:$dst)>;
|
||||
def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
|
||||
}
|
||||
let Predicates = [IsN64, HasStandardEncoding] in {
|
||||
def : MipsPat<(store_a (i32 0), addr:$dst), (SW_P8 ZERO, addr:$dst)>;
|
||||
def : MipsPat<(store_u (i32 0), addr:$dst), (USW_P8 ZERO, addr:$dst)>;
|
||||
def : MipsPat<(store (i32 0), addr:$dst), (SW_P8 ZERO, addr:$dst)>;
|
||||
}
|
||||
|
||||
// brcond patterns
|
||||
|
Loading…
Reference in New Issue
Block a user