mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-18 11:05:48 -04:00
Added support for 32 bit writes, fixed load/store merge optimizations
This commit is contained in:
parent
e2cc8de914
commit
b14953d75a
@ -33,7 +33,10 @@ public:
|
||||
PtrDiffType = SignedInt;
|
||||
IntPtrType = SignedInt;
|
||||
UseZeroLengthBitfieldAlignment = true;
|
||||
resetDataLayout("e-m:e-P1-p0:16:16:16-p1:32:16:16-i1:16:16-i8:16:16-i16:16:16-i32:16:16-a:0:16-n16:40");
|
||||
BoolWidth = 16;
|
||||
BoolAlign = 16;
|
||||
MinGlobalAlign = 16;
|
||||
resetDataLayout("E-m:e-P1-p0:16:16:16-p1:32:32:32-i1:16:16-i8:16:16-i16:16:16-i32:32:32-a:0:32-n16:40");
|
||||
}
|
||||
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
|
@ -20851,9 +20851,9 @@ bool DAGCombiner::isAlias(SDNode *Op0, SDNode *Op1) const {
|
||||
int64_t Offset = 0;
|
||||
if (auto *C = dyn_cast<ConstantSDNode>(LSN->getOffset()))
|
||||
Offset = (LSN->getAddressingMode() == ISD::PRE_INC)
|
||||
? C->getSExtValue()
|
||||
? C->getSExtValue() << 1
|
||||
: (LSN->getAddressingMode() == ISD::PRE_DEC)
|
||||
? -1 * C->getSExtValue()
|
||||
? -1 * C->getSExtValue() << 1
|
||||
: 0;
|
||||
uint64_t Size =
|
||||
MemoryLocation::getSizeOrUnknown(LSN->getMemoryVT().getStoreSize());
|
||||
@ -20920,8 +20920,8 @@ bool DAGCombiner::isAlias(SDNode *Op0, SDNode *Op1) const {
|
||||
// alignment compared to the size and offset of the access, we may be able
|
||||
// to prove they do not alias. This check is conservative for now to catch
|
||||
// cases created by splitting vector types.
|
||||
int64_t SrcValOffset0 = MUC0.MMO->getOffset();
|
||||
int64_t SrcValOffset1 = MUC1.MMO->getOffset();
|
||||
int64_t SrcValOffset0 = MUC0.MMO->getOffset() << 1;
|
||||
int64_t SrcValOffset1 = MUC1.MMO->getOffset() << 1;
|
||||
unsigned OrigAlignment0 = MUC0.MMO->getBaseAlignment();
|
||||
unsigned OrigAlignment1 = MUC1.MMO->getBaseAlignment();
|
||||
if (OrigAlignment0 == OrigAlignment1 && SrcValOffset0 != SrcValOffset1 &&
|
||||
|
@ -549,7 +549,7 @@ void SelectionDAGLegalize::LegalizeStoreOps(SDNode *Node) {
|
||||
// storing an integral number of bytes. For example, promote
|
||||
// TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1)
|
||||
EVT NVT = EVT::getIntegerVT(*DAG.getContext(),
|
||||
StVT.getStoreSizeInBits());
|
||||
(StVT.getStoreSizeInBits() + 0xF) & ~0xF);
|
||||
Value = DAG.getZeroExtendInReg(Value, dl, StVT);
|
||||
SDValue Result =
|
||||
DAG.getTruncStore(Chain, dl, Value, Ptr, ST->getPointerInfo(), NVT,
|
||||
@ -738,7 +738,7 @@ void SelectionDAGLegalize::LegalizeLoadOps(SDNode *Node) {
|
||||
TargetLowering::Promote)) {
|
||||
// Promote to a byte-sized load if not loading an integral number of
|
||||
// bytes. For example, promote EXTLOAD:i20 -> EXTLOAD:i24.
|
||||
unsigned NewWidth = SrcVT.getStoreSizeInBits();
|
||||
unsigned NewWidth = (SrcVT.getStoreSizeInBits() + 0xF) & ~0xF;
|
||||
EVT NVT = EVT::getIntegerVT(*DAG.getContext(), NewWidth);
|
||||
SDValue Ch;
|
||||
|
||||
|
@ -39,7 +39,7 @@ bool BaseIndexOffset::equalBaseIndex(const BaseIndexOffset &Other,
|
||||
if (auto *A = dyn_cast<GlobalAddressSDNode>(Base))
|
||||
if (auto *B = dyn_cast<GlobalAddressSDNode>(Other.Base))
|
||||
if (A->getGlobal() == B->getGlobal()) {
|
||||
Off += B->getOffset() - A->getOffset();
|
||||
Off += (B->getOffset() - A->getOffset()) << 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ bool BaseIndexOffset::equalBaseIndex(const BaseIndexOffset &Other,
|
||||
IsMatch = A->getConstVal() == B->getConstVal();
|
||||
}
|
||||
if (IsMatch) {
|
||||
Off += B->getOffset() - A->getOffset();
|
||||
Off += (B->getOffset() - A->getOffset()) << 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -238,7 +238,7 @@ static BaseIndexOffset matchLSNode(const LSBaseSDNode *N,
|
||||
// (i64 mul (i64 %induction_var)
|
||||
// (i64 %element_size)))
|
||||
if (Base->getOperand(1)->getOpcode() == ISD::MUL)
|
||||
return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt);
|
||||
return BaseIndexOffset(Base, Index, Offset << 1, IsIndexSignExt);
|
||||
|
||||
// Look at Base + Index + Offset cases.
|
||||
Index = Base->getOperand(1);
|
||||
@ -253,7 +253,7 @@ static BaseIndexOffset matchLSNode(const LSBaseSDNode *N,
|
||||
// Check if Index Offset pattern
|
||||
if (Index->getOpcode() != ISD::ADD ||
|
||||
!isa<ConstantSDNode>(Index->getOperand(1)))
|
||||
return BaseIndexOffset(PotentialBase, Index, Offset, IsIndexSignExt);
|
||||
return BaseIndexOffset(PotentialBase, Index, Offset << 1, IsIndexSignExt);
|
||||
|
||||
Offset += cast<ConstantSDNode>(Index->getOperand(1))->getSExtValue();
|
||||
Index = Index->getOperand(0);
|
||||
@ -264,7 +264,7 @@ static BaseIndexOffset matchLSNode(const LSBaseSDNode *N,
|
||||
IsIndexSignExt = false;
|
||||
Base = PotentialBase;
|
||||
}
|
||||
return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt);
|
||||
return BaseIndexOffset(Base, Index, Offset << 1, IsIndexSignExt);
|
||||
}
|
||||
|
||||
BaseIndexOffset BaseIndexOffset::match(const SDNode *N,
|
||||
@ -273,7 +273,7 @@ BaseIndexOffset BaseIndexOffset::match(const SDNode *N,
|
||||
return matchLSNode(LS0, DAG);
|
||||
if (const auto *LN = dyn_cast<LifetimeSDNode>(N)) {
|
||||
if (LN->hasOffset())
|
||||
return BaseIndexOffset(LN->getOperand(1), SDValue(), LN->getOffset(),
|
||||
return BaseIndexOffset(LN->getOperand(1), SDValue(), LN->getOffset() << 1,
|
||||
false);
|
||||
return BaseIndexOffset(LN->getOperand(1), SDValue(), false);
|
||||
}
|
||||
|
@ -70,6 +70,28 @@ void TeakInstPrinter::printCondCode(const MCInst *MI, unsigned OpNum, raw_ostrea
|
||||
O << TeakCCondCodeToString((TeakCC::CondCodes)MI->getOperand(OpNum).getImm());
|
||||
}
|
||||
|
||||
void TeakInstPrinter::printMemR0425(const MCInst *MI, unsigned OpNum, raw_ostream &O)
|
||||
{
|
||||
const MCOperand& op = MI->getOperand(OpNum);
|
||||
switch(op.getReg())
|
||||
{
|
||||
case Teak::R0:
|
||||
O << "arrn0+ars0";
|
||||
break;
|
||||
case Teak::R4:
|
||||
O << "arrn1+ars0";
|
||||
break;
|
||||
case Teak::R2:
|
||||
O << "arrn2+ars0";
|
||||
break;
|
||||
case Teak::R5:
|
||||
O << "arrn3+ars0";
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Invalid MemR0425 operand!");
|
||||
}
|
||||
}
|
||||
|
||||
// Print a 'memsrc' operand which is a (Register, Offset) pair.
|
||||
void TeakInstPrinter::printAddrModeMemSrc(const MCInst *MI, unsigned OpNum, raw_ostream &O)
|
||||
{
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
|
||||
private:
|
||||
void printCondCode(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||
void printMemR0425(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||
void printAddrModeMemSrc(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printMemOperand(const MCInst *MI, int opNum, raw_ostream &O);
|
||||
|
@ -267,6 +267,21 @@ static unsigned encodeRnOp(unsigned reg)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned encodeMemR0425Op(unsigned reg)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case Teak::R0: return 0;
|
||||
case Teak::R4: return 1;
|
||||
case Teak::R2: return 2;
|
||||
case Teak::R5: return 3;
|
||||
default:
|
||||
dbgs() << "encodeMemR0425Op(" << reg << ")\n";
|
||||
llvm_unreachable("Unsupported register");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned encodeArArpSttModOp(unsigned reg)
|
||||
{
|
||||
switch (reg)
|
||||
@ -640,6 +655,12 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
EmitConstant(0x1C00 | encodeRnOp(MI.getOperand(1).getReg()) | (step << 3) | (encodeRegisterOp(dstReg) << 5), 2, OS);
|
||||
break;
|
||||
}
|
||||
case Teak::MOV_memr0425_ab:
|
||||
EmitConstant(0x4BC0 | (encodeMemR0425Op(MI.getOperand(1).getReg()) << 2) | (encodeAbOp(MI.getOperand(0).getReg()) << 4), 2, OS);
|
||||
break;
|
||||
case Teak::MOV_ab_memr0425:
|
||||
EmitConstant(0x4DC0 | (encodeMemR0425Op(MI.getOperand(1).getReg()) << 2) | (encodeAbOp(MI.getOperand(0).getReg()) << 4), 2, OS);
|
||||
break;
|
||||
case Teak::MOV_r7offset7s_a:
|
||||
EmitConstant(0xD880 | (encodeAxOp(MI.getOperand(0).getReg()) << 8) | (MI.getOperand(2).getImm() & 0x7F), 2, OS);
|
||||
break;
|
||||
|
@ -189,6 +189,29 @@ TeakTargetLowering::TeakTargetLowering(const TeakTargetMachine &TeakTM)
|
||||
// setOperationAction(ISD::CopyToReg, MVT::i32, Custom);
|
||||
// setOperationAction(ISD::CopyFromReg, MVT::i32, Custom);
|
||||
// setOperationAction(ISD::CopyToReg, MVT::i40, Expand);
|
||||
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::i40, MVT::i32, Expand);
|
||||
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::i16, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::i40, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::i16, MVT::i8, Promote);
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::i40, MVT::i8, Promote);
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::i16, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::i40, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::i16, MVT::i8, Promote);
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::i40, MVT::i8, Promote);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i16, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i40, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i16, MVT::i8, Promote);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i40, MVT::i8, Promote);
|
||||
|
||||
setTruncStoreAction(MVT::i40, MVT::i1, Expand);
|
||||
setTruncStoreAction(MVT::i32, MVT::i1, Expand);
|
||||
setTruncStoreAction(MVT::i16, MVT::i1, Expand);
|
||||
setTruncStoreAction(MVT::i8, MVT::i1, Expand);
|
||||
setTruncStoreAction(MVT::i40, MVT::i8, Expand);
|
||||
setTruncStoreAction(MVT::i32, MVT::i8, Expand);
|
||||
setTruncStoreAction(MVT::i16, MVT::i8, Expand);
|
||||
}
|
||||
|
||||
// SDValue TeakTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const
|
||||
@ -437,7 +460,7 @@ SDValue TeakTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
|
||||
// dbgs() << "constant!\n";
|
||||
// return Op;
|
||||
// }
|
||||
dbgs() << "Lowering!\n";
|
||||
//dbgs() << "Lowering!\n";
|
||||
SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i40, N->getOperand(0));
|
||||
SDValue NewOp1 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i40, N->getOperand(1));
|
||||
SDValue NewWOp = DAG.getNode(Op.getOpcode(), dl, MVT::i40, NewOp0, NewOp1);
|
||||
|
@ -152,6 +152,11 @@ def pred : PredicateOperand<OtherVT, (ops i32imm, i32imm), (ops (i32 0), (i32 ze
|
||||
let PrintMethod = "printCondCode";
|
||||
}
|
||||
|
||||
def MemR0425 : RegisterOperand<RegR0425>
|
||||
{
|
||||
let PrintMethod = "printMemR0425";
|
||||
}
|
||||
|
||||
// // sext_inreg
|
||||
// def : Pat<(sext_inreg i16:$src, i8),
|
||||
// (SEXT (i8 (EXTRACT_SUBREG i16:$src, sub_lo)))>;
|
||||
@ -396,6 +401,12 @@ def MOV_memrn_ab : InstTeak<(outs ABRegs:$dst), (ins GRRegs:$srcAddr), "mov [$sr
|
||||
let Defs = [ICC], mayLoad = 1 in
|
||||
def MOV_memrn_ab1 : InstTeak<(outs ABRegs:$dst), (ins GRRegs:$srcAddr), "mov [$srcAddr], ${dst}l", [(set ABRegs:$dst, (zextloadi16 GRRegs:$srcAddr))]>;
|
||||
|
||||
let Defs = [ICC], mayLoad = 1 in
|
||||
def MOV_memr0425_ab : InstTeak<(outs ABRegs:$dst), (ins MemR0425:$srcAddr), "mov [$srcAddr], $dst", [(set ABRegs:$dst, (sextloadi32 MemR0425:$srcAddr))]>;
|
||||
|
||||
let mayStore = 1 in
|
||||
def MOV_ab_memr0425 : InstTeak<(outs), (ins ABRegs:$src, MemR0425:$dstAddr), "mov $src, [$dstAddr]", [(truncstorei32 ABRegs:$src, MemR0425:$dstAddr)]>;
|
||||
|
||||
// let mayStore = 1 in
|
||||
// def MOV_a_r7offset16 : InstTeak<
|
||||
// (outs),
|
||||
@ -549,4 +560,6 @@ def : Pat<(i16 (TeakWrapper tglobaladdr:$dst)), (MOV_imm16_regnob16 tglobaladdr:
|
||||
// anyextload
|
||||
def : Pat<(extloadi16 tglobaladdr:$srcAddr), (MOV_memimm16_a tglobaladdr:$srcAddr)>;
|
||||
def : Pat<(extloadi16 imm:$srcAddr), (MOV_memimm16_a imm:$srcAddr)>;
|
||||
def : Pat<(extloadi16 GRRegs:$srcAddr), (MOV_memrn_ab1 GRRegs:$srcAddr)>;
|
||||
def : Pat<(extloadi16 GRRegs:$srcAddr), (MOV_memrn_ab1 GRRegs:$srcAddr)>;
|
||||
|
||||
def : Pat<(extloadi32 MemR0425:$srcAddr), (MOV_memr0425_ab MemR0425:$srcAddr)>;
|
@ -104,6 +104,7 @@ def RegNoBRegs40 : RegisterClass<"Teak", [i40], 32, (add A0, A1)>;
|
||||
def RegNoBRegs16 : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, B0H, B1H, B0L, B1L, A0L, A1L, A0H, A1H, LC, SV)>;
|
||||
def RegNoBRegs16_nolh : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, LC, SV)>;
|
||||
def RegNoBRegs16_noh : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, A0L, A1L, B0L, B1L, LC, SV)>;
|
||||
def RegR0425 : RegisterClass<"Teak", [i16], 16, (add R0, R4, R2, R5)>;
|
||||
//def RegNoBRegsP040 : RegisterClass<"Teak", [i40], 32, (add A0, A1)>;
|
||||
//def RegNoBRegsP016 : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R7, Y0, /**/ SP, B0H, B1H, B0L, B1L, A0L, A1L, A0H, A1H, LC, SV)>;
|
||||
def ARegs : RegisterClass<"Teak", [i40], 32, (add A0, A1)>;
|
||||
|
@ -28,5 +28,5 @@ void TeakSubtarget::anchor() {}
|
||||
TeakSubtarget::TeakSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS,
|
||||
const TeakTargetMachine &TM)
|
||||
: TeakGenSubtargetInfo(TT, CPU, FS),
|
||||
DL("e-m:e-P1-p0:16:16:16-p1:32:16:16-i1:16:16-i8:16:16-i16:16:16-i32:16:16-a:0:16-n16:40"),
|
||||
DL("E-m:e-P1-p0:16:16:16-p1:32:32:32-i1:16:16-i8:16:16-i16:16:16-i32:32:32-a:0:32-n16:40"),
|
||||
InstrInfo(), TLInfo(TM), TSInfo(), FrameLowering() {}
|
@ -30,7 +30,7 @@ static std::string computeDataLayout(const Triple &TT, StringRef CPU,
|
||||
const TargetOptions &Options) {
|
||||
// XXX Build the triple from the arguments.
|
||||
// This is hard-coded for now for this example target.
|
||||
return "e-m:e-P1-p0:16:16:16-p1:32:16:16-i1:16:16-i8:16:16-i16:16:16-i32:16:16-a:0:16-n16:40";
|
||||
return "E-m:e-P1-p0:16:16:16-p1:32:32:32-i1:16:16-i8:16:16-i16:16:16-i32:32:32-a:0:32-n16:40";
|
||||
}
|
||||
|
||||
static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
|
||||
|
Loading…
Reference in New Issue
Block a user