From 7fd1edd32e9a6782dbcd00818bbdaf82f14284a1 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Mon, 19 Dec 2005 23:25:09 +0000 Subject: [PATCH] Convert load/store over to being pattern matched git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24871 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCAsmPrinter.cpp | 14 +- lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 216 ++++++++----------------- lib/Target/PowerPC/PPCISelLowering.cpp | 1 + lib/Target/PowerPC/PPCInstrInfo.td | 194 +++++++++++++--------- 4 files changed, 202 insertions(+), 223 deletions(-) diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index cb27e1f3888..9cf686353a6 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -181,7 +181,19 @@ namespace { unsigned RegNo = enumRegToMachineReg(CCReg); O << (0x80 >> RegNo); } - + // The new addressing mode printers, currently empty + void printMemRegImm(const MachineInstr *MI, unsigned OpNo) { + printSymbolLo(MI, OpNo); + O << '('; + printOperand(MI, OpNo+1); + O << ')'; + } + void printMemRegReg(const MachineInstr *MI, unsigned OpNo) { + printOperand(MI, OpNo); + O << ", "; + printOperand(MI, OpNo+1); + } + virtual bool runOnMachineFunction(MachineFunction &F) = 0; virtual bool doFinalization(Module &M) = 0; }; diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index ce2b178445a..b9550f50fa4 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -68,15 +68,18 @@ namespace { /// specified condition code, returning the CR# of the expression. SDOperand SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC); - /// SelectAddr - Given the specified address, return the two operands for a - /// load/store instruction, and return true if it should be an indexed [r+r] - /// operation. - bool SelectAddr(SDOperand Addr, SDOperand &Op1, SDOperand &Op2); + /// SelectAddrImm - Returns true if the address N can be represented by + /// a base register plus a signed 16-bit displacement [r+imm]. + bool SelectAddrImm(SDOperand N, SDOperand &Disp, SDOperand &Base); + + /// SelectAddrIdx - Given the specified addressed, check to see if it can be + /// represented as an indexed [r+r] operation. Returns false if it can + /// be represented by [r+imm], which are preferred. + bool SelectAddrIdx(SDOperand N, SDOperand &Base, SDOperand &Index); - /// SelectAddrIndexed - Given the specified addressed, force it to be - /// represented as an indexed [r+r] operation, rather than possibly - /// returning [r+imm] as SelectAddr may. - void SelectAddrIndexed(SDOperand Addr, SDOperand &Op1, SDOperand &Op2); + /// SelectAddrIdxOnly - Given the specified addressed, force it to be + /// represented as an indexed [r+r] operation. + bool SelectAddrIdxOnly(SDOperand N, SDOperand &Base, SDOperand &Index); SDOperand BuildSDIVSequence(SDNode *N); SDOperand BuildUDIVSequence(SDNode *N); @@ -400,65 +403,77 @@ SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) { return 0; } -/// SelectAddr - Given the specified address, return the two operands for a -/// load/store instruction, and return true if it should be an indexed [r+r] -/// operation. -bool PPCDAGToDAGISel::SelectAddr(SDOperand Addr, SDOperand &Op1, - SDOperand &Op2) { - unsigned imm = 0; - if (Addr.getOpcode() == ISD::ADD) { - if (isIntImmediate(Addr.getOperand(1), imm) && isInt16(imm)) { - Op1 = getI32Imm(Lo16(imm)); - if (FrameIndexSDNode *FI = - dyn_cast(Addr.getOperand(0))) { - ++FrameOff; - Op2 = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); +/// SelectAddrImm - Returns true if the address N can be represented by +/// a base register plus a signed 16-bit displacement [r+imm]. +bool PPCDAGToDAGISel::SelectAddrImm(SDOperand N, SDOperand &Disp, + SDOperand &Base) { + if (N.getOpcode() == ISD::ADD) { + unsigned imm = 0; + if (isIntImmediate(N.getOperand(1), imm) && isInt16(imm)) { + Disp = getI32Imm(Lo16(imm)); + if (FrameIndexSDNode *FI = dyn_cast(N.getOperand(0))) { + Base = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); } else { - Op2 = Select(Addr.getOperand(0)); + Base = Select(N.getOperand(0)); } - return false; - } else if (Addr.getOperand(1).getOpcode() == PPCISD::Lo) { + return true; // [r+i] + } else if (N.getOperand(1).getOpcode() == PPCISD::Lo) { // Match LOAD (ADD (X, Lo(G))). - assert(!cast(Addr.getOperand(1).getOperand(1))->getValue() + assert(!cast(N.getOperand(1).getOperand(1))->getValue() && "Cannot handle constant offsets yet!"); - Op1 = Addr.getOperand(1).getOperand(0); // The global address. - assert(Op1.getOpcode() == ISD::TargetGlobalAddress || - Op1.getOpcode() == ISD::TargetConstantPool); - Op2 = Select(Addr.getOperand(0)); - return false; // [&g+r] - } else { - Op1 = Select(Addr.getOperand(0)); - Op2 = Select(Addr.getOperand(1)); - return true; // [r+r] + Disp = N.getOperand(1).getOperand(0); // The global address. + assert(Disp.getOpcode() == ISD::TargetGlobalAddress || + Disp.getOpcode() == ISD::TargetConstantPool); + Base = Select(N.getOperand(0)); + return true; // [&g+r] } + return false; // [r+r] } - - if (FrameIndexSDNode *FI = dyn_cast(Addr)) - Op2 = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); + Disp = getI32Imm(0); + if (FrameIndexSDNode *FI = dyn_cast(N)) + Base = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); else - Op2 = Select(Addr); - Op1 = getI32Imm(0); - return false; + Base = Select(N); + return true; // [r+0] } -/// SelectAddrIndexed - Given the specified addressed, force it to be -/// represented as an indexed [r+r] operation, rather than possibly -/// returning [r+imm] as SelectAddr may. -void PPCDAGToDAGISel::SelectAddrIndexed(SDOperand Addr, SDOperand &Op1, - SDOperand &Op2) { - if (Addr.getOpcode() == ISD::ADD) { - Op1 = Select(Addr.getOperand(0)); - Op2 = Select(Addr.getOperand(1)); - return; - } +/// SelectAddrIdx - Given the specified addressed, check to see if it can be +/// represented as an indexed [r+r] operation. Returns false if it can +/// be represented by [r+imm], which are preferred. +bool PPCDAGToDAGISel::SelectAddrIdx(SDOperand N, SDOperand &Base, + SDOperand &Index) { + // Check to see if we can represent this as an [r+imm] address instead, + // which will fail if the address is more profitably represented as an + // [r+r] address. + if (SelectAddrImm(N, Base, Index)) + return false; - if (FrameIndexSDNode *FI = dyn_cast(Addr)) { - Op1 = CurDAG->getTargetNode(PPC::LI, MVT::i32, getI32Imm(0)); - Op2 = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); - return; + if (N.getOpcode() == ISD::ADD) { + Base = Select(N.getOperand(0)); + Index = Select(N.getOperand(1)); + return true; + } + + // FIXME: This should be a CopyFromReg R0 rather than a load of 0. + Base = CurDAG->getTargetNode(PPC::LI, MVT::i32, getI32Imm(0)); + Index = Select(N); + return true; +} + +/// SelectAddrIdxOnly - Given the specified addressed, force it to be +/// represented as an indexed [r+r] operation. +bool PPCDAGToDAGISel::SelectAddrIdxOnly(SDOperand N, SDOperand &Base, + SDOperand &Index) { + if (N.getOpcode() == ISD::ADD) { + Base = Select(N.getOperand(0)); + Index = Select(N.getOperand(1)); + return true; } - Op1 = CurDAG->getTargetNode(PPC::LI, MVT::i32, getI32Imm(0)); - Op2 = Select(Addr); + + // FIXME: This should be a CopyFromReg R0 rather than a load of 0. + Base = CurDAG->getTargetNode(PPC::LI, MVT::i32, getI32Imm(0)); + Index = Select(N); + return true; } /// SelectCC - Select a comparison of the specified values with the specified @@ -997,95 +1012,6 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) { // Other cases are autogenerated. break; } - case ISD::LOAD: - case ISD::EXTLOAD: - case ISD::ZEXTLOAD: - case ISD::SEXTLOAD: { - SDOperand Op1, Op2; - // If this is a vector load, then force this to be indexed addressing, since - // altivec does not have immediate offsets for loads. - bool isIdx = true; - if (N->getOpcode() == ISD::LOAD && MVT::isVector(N->getValueType(0))) { - SelectAddrIndexed(N->getOperand(1), Op1, Op2); - } else { - isIdx = SelectAddr(N->getOperand(1), Op1, Op2); - } - MVT::ValueType TypeBeingLoaded = (N->getOpcode() == ISD::LOAD) ? - N->getValueType(0) : cast(N->getOperand(3))->getVT(); - - unsigned Opc; - switch (TypeBeingLoaded) { - default: N->dump(); assert(0 && "Cannot load this type!"); - case MVT::i1: - case MVT::i8: Opc = isIdx ? PPC::LBZX : PPC::LBZ; break; - case MVT::i16: - if (N->getOpcode() == ISD::SEXTLOAD) { // SEXT load? - Opc = isIdx ? PPC::LHAX : PPC::LHA; - } else { - Opc = isIdx ? PPC::LHZX : PPC::LHZ; - } - break; - case MVT::i32: Opc = isIdx ? PPC::LWZX : PPC::LWZ; break; - case MVT::f32: Opc = isIdx ? PPC::LFSX : PPC::LFS; break; - case MVT::f64: Opc = isIdx ? PPC::LFDX : PPC::LFD; break; - case MVT::v4f32: Opc = PPC::LVX; break; - } - - // If this is an f32 -> f64 load, emit the f32 load, then use an 'extending - // copy'. - if (TypeBeingLoaded != MVT::f32 || N->getOpcode() == ISD::LOAD) { - return CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other, - Op1, Op2, Select(N->getOperand(0))). - getValue(Op.ResNo); - } else { - std::vector Ops; - Ops.push_back(Op1); - Ops.push_back(Op2); - Ops.push_back(Select(N->getOperand(0))); - SDOperand Res = CurDAG->getTargetNode(Opc, MVT::f32, MVT::Other, Ops); - SDOperand Ext = CurDAG->getTargetNode(PPC::FMRSD, MVT::f64, Res); - CodeGenMap[Op.getValue(0)] = Ext; - CodeGenMap[Op.getValue(1)] = Res.getValue(1); - if (Op.ResNo) - return Res.getValue(1); - else - return Ext; - } - } - case ISD::TRUNCSTORE: - case ISD::STORE: { - SDOperand AddrOp1, AddrOp2; - // If this is a vector store, then force this to be indexed addressing, - // since altivec does not have immediate offsets for stores. - bool isIdx = true; - if (N->getOpcode() == ISD::STORE && - MVT::isVector(N->getOperand(1).getValueType())) { - SelectAddrIndexed(N->getOperand(2), AddrOp1, AddrOp2); - } else { - isIdx = SelectAddr(N->getOperand(2), AddrOp1, AddrOp2); - } - - unsigned Opc; - if (N->getOpcode() == ISD::STORE) { - switch (N->getOperand(1).getValueType()) { - default: assert(0 && "unknown Type in store"); - case MVT::i32: Opc = isIdx ? PPC::STWX : PPC::STW; break; - case MVT::f64: Opc = isIdx ? PPC::STFDX : PPC::STFD; break; - case MVT::f32: Opc = isIdx ? PPC::STFSX : PPC::STFS; break; - case MVT::v4f32: Opc = PPC::STVX; - } - } else { //ISD::TRUNCSTORE - switch(cast(N->getOperand(4))->getVT()) { - default: assert(0 && "unknown Type in store"); - case MVT::i8: Opc = isIdx ? PPC::STBX : PPC::STB; break; - case MVT::i16: Opc = isIdx ? PPC::STHX : PPC::STH; break; - } - } - - return CurDAG->SelectNodeTo(N, Opc, MVT::Other, Select(N->getOperand(1)), - AddrOp1, AddrOp2, Select(N->getOperand(0))); - } - case ISD::SELECT_CC: { ISD::CondCode CC = cast(N->getOperand(4))->get(); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 27df47c50a5..ba3fa0ed2c9 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -126,6 +126,7 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) // FIXME: AltiVec supports a wide variety of packed types. For now, we're // bringing up support with just v4f32. addRegisterClass(MVT::v4f32, PPC::VRRCRegisterClass); + addRegisterClass(MVT::v4i32, PPC::VRRCRegisterClass); } setSetCCResultContents(ZeroOrOneSetCCResult); diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index af7560b648c..12a6cfba4f7 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -165,6 +165,22 @@ def symbolLo: Operand { def crbitm: Operand { let PrintMethod = "printcrbitm"; } +// Address operands +def memri : Operand { + let PrintMethod = "printMemRegImm"; + let NumMIOperands = 2; + let MIOperandInfo = (ops i32imm, GPRC); +} +def memrr : Operand { + let PrintMethod = "printMemRegReg"; + let NumMIOperands = 2; + let MIOperandInfo = (ops GPRC, GPRC); +} + +// Define X86 specific addressing mode. +def iaddr : ComplexPattern; +def xaddr : ComplexPattern; +def xoaddr : ComplexPattern; //===----------------------------------------------------------------------===// // PowerPC Instruction Predicate Definitions. @@ -258,21 +274,21 @@ let isCall = 1, // register and an immediate are of this type. // let isLoad = 1 in { -def LBZ : DForm_1<34, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lbz $rD, $disp($rA)", LdStGeneral, - []>; -def LHA : DForm_1<42, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lha $rD, $disp($rA)", LdStLHA, - []>; -def LHZ : DForm_1<40, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lhz $rD, $disp($rA)", LdStGeneral, - []>; +def LBZ : DForm_1<34, (ops GPRC:$rD, memri:$src), + "lbz $rD, $src", LdStGeneral, + [(set GPRC:$rD, (zextload iaddr:$src, i8))]>; +def LHA : DForm_1<42, (ops GPRC:$rD, memri:$src), + "lha $rD, $src", LdStLHA, + [(set GPRC:$rD, (sextload iaddr:$src, i16))]>; +def LHZ : DForm_1<40, (ops GPRC:$rD, memri:$src), + "lhz $rD, $src", LdStGeneral, + [(set GPRC:$rD, (zextload iaddr:$src, i16))]>; def LMW : DForm_1<46, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA), "lmw $rD, $disp($rA)", LdStLMW, []>; -def LWZ : DForm_1<32, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lwz $rD, $disp($rA)", LdStGeneral, - []>; +def LWZ : DForm_1<32, (ops GPRC:$rD, memri:$src), + "lwz $rD, $src", LdStGeneral, + [(set GPRC:$rD, (load iaddr:$src))]>; def LWZU : DForm_1<35, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA), "lwzu $rD, $disp($rA)", LdStGeneral, []>; @@ -309,15 +325,15 @@ let isStore = 1 in { def STMW : DForm_3<47, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), "stmw $rS, $disp($rA)", LdStLMW, []>; -def STB : DForm_3<38, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), - "stb $rS, $disp($rA)", LdStGeneral, - []>; -def STH : DForm_3<44, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), - "sth $rS, $disp($rA)", LdStGeneral, - []>; -def STW : DForm_3<36, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), - "stw $rS, $disp($rA)", LdStGeneral, - []>; +def STB : DForm_3<38, (ops GPRC:$rS, memri:$src), + "stb $rS, $src", LdStGeneral, + [(truncstore GPRC:$rS, iaddr:$src, i8)]>; +def STH : DForm_3<44, (ops GPRC:$rS, memri:$src), + "sth $rS, $src", LdStGeneral, + [(truncstore GPRC:$rS, iaddr:$src, i16)]>; +def STW : DForm_3<36, (ops GPRC:$rS, memri:$src), + "stw $rS, $src", LdStGeneral, + [(store GPRC:$rS, iaddr:$src)]>; def STWU : DForm_3<37, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), "stwu $rS, $disp($rA)", LdStGeneral, []>; @@ -355,20 +371,20 @@ def CMPLWI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2), def CMPLDI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2), "cmpldi $dst, $src1, $src2", IntCompare>, isPPC64; let isLoad = 1 in { -def LFS : DForm_8<48, (ops F4RC:$rD, symbolLo:$disp, GPRC:$rA), - "lfs $rD, $disp($rA)", LdStLFDU, - []>; -def LFD : DForm_8<50, (ops F8RC:$rD, symbolLo:$disp, GPRC:$rA), - "lfd $rD, $disp($rA)", LdStLFD, - []>; +def LFS : DForm_8<48, (ops F4RC:$rD, memri:$src), + "lfs $rD, $src", LdStLFDU, + [(set F4RC:$rD, (load iaddr:$src))]>; +def LFD : DForm_8<50, (ops F8RC:$rD, memri:$src), + "lfd $rD, $src", LdStLFD, + [(set F8RC:$rD, (load iaddr:$src))]>; } let isStore = 1 in { -def STFS : DForm_9<52, (ops F4RC:$rS, symbolLo:$disp, GPRC:$rA), - "stfs $rS, $disp($rA)", LdStUX, - []>; -def STFD : DForm_9<54, (ops F8RC:$rS, symbolLo:$disp, GPRC:$rA), - "stfd $rS, $disp($rA)", LdStUX, - []>; +def STFS : DForm_9<52, (ops F4RC:$rS, memri:$dst), + "stfs $rS, $dst", LdStUX, + [(store F4RC:$rS, iaddr:$dst)]>; +def STFD : DForm_9<54, (ops F8RC:$rS, memri:$dst), + "stfd $rS, $dst", LdStUX, + [(store F8RC:$rS, iaddr:$dst)]>; } // DS-Form instructions. Load/Store instructions available in PPC-64 @@ -394,24 +410,24 @@ def STDU : DSForm_2<62, 1, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), // register and another register are of this type. // let isLoad = 1 in { -def LBZX : XForm_1<31, 87, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lbzx $dst, $base, $index", LdStGeneral, - []>; -def LHAX : XForm_1<31, 343, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lhax $dst, $base, $index", LdStLHA, - []>; -def LHZX : XForm_1<31, 279, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lhzx $dst, $base, $index", LdStGeneral, - []>; -def LWAX : XForm_1<31, 341, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lwax $dst, $base, $index", LdStLHA, - []>, isPPC64; -def LWZX : XForm_1<31, 23, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lwzx $dst, $base, $index", LdStGeneral, - []>; -def LDX : XForm_1<31, 21, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "ldx $dst, $base, $index", LdStLD, - []>, isPPC64; +def LBZX : XForm_1<31, 87, (ops GPRC:$rD, memrr:$src), + "lbzx $rD, $src", LdStGeneral, + [(set GPRC:$rD, (zextload xaddr:$src, i8))]>; +def LHAX : XForm_1<31, 343, (ops GPRC:$rD, memrr:$src), + "lhax $rD, $src", LdStLHA, + [(set GPRC:$rD, (sextload xaddr:$src, i16))]>; +def LHZX : XForm_1<31, 279, (ops GPRC:$rD, memrr:$src), + "lhzx $rD, $src", LdStGeneral, + [(set GPRC:$rD, (zextload xaddr:$src, i16))]>; +def LWAX : XForm_1<31, 341, (ops G8RC:$rD, memrr:$src), + "lwax $rD, $src", LdStLHA, + [(set G8RC:$rD, (sextload xaddr:$src, i32))]>, isPPC64; +def LWZX : XForm_1<31, 23, (ops GPRC:$rD, memrr:$src), + "lwzx $rD, $src", LdStGeneral, + [(set GPRC:$rD, (load xaddr:$src))]>; +def LDX : XForm_1<31, 21, (ops G8RC:$rD, memrr:$src), + "ldx $rD, $src", LdStLD, + [(set G8RC:$rD, (load xaddr:$src))]>, isPPC64; def LVEBX: XForm_1<31, 7, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), "lvebx $vD, $base, $rA", LdStGeneral, []>; @@ -421,9 +437,9 @@ def LVEHX: XForm_1<31, 39, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), def LVEWX: XForm_1<31, 71, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), "lvewx $vD, $base, $rA", LdStGeneral, []>; -def LVX : XForm_1<31, 103, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), - "lvx $vD, $base, $rA", LdStGeneral, - []>; +def LVX : XForm_1<31, 103, (ops VRRC:$vD, memrr:$src), + "lvx $vD, $src", LdStGeneral, + [(set VRRC:$vD, (load xoaddr:$src))]>; } def LVSL : XForm_1<31, 6, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), "lvsl $vD, $base, $rA", LdStGeneral, @@ -489,15 +505,15 @@ def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "sraw $rA, $rS, $rB", IntShift, [(set GPRC:$rA, (PPCsra GPRC:$rS, GPRC:$rB))]>; let isStore = 1 in { -def STBX : XForm_8<31, 215, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "stbx $rS, $rA, $rB", LdStGeneral, - []>; -def STHX : XForm_8<31, 407, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "sthx $rS, $rA, $rB", LdStGeneral, - []>; -def STWX : XForm_8<31, 151, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "stwx $rS, $rA, $rB", LdStGeneral, - []>; +def STBX : XForm_8<31, 215, (ops GPRC:$rS, memrr:$dst), + "stbx $rS, $dst", LdStGeneral, + [(truncstore GPRC:$rS, xaddr:$dst, i8)]>; +def STHX : XForm_8<31, 407, (ops GPRC:$rS, memrr:$dst), + "sthx $rS, $dst", LdStGeneral, + [(truncstore GPRC:$rS, xaddr:$dst, i16)]>; +def STWX : XForm_8<31, 151, (ops GPRC:$rS, memrr:$dst), + "stwx $rS, $dst", LdStGeneral, + [(store GPRC:$rS, xaddr:$dst)]>; def STWUX : XForm_8<31, 183, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), "stwux $rS, $rA, $rB", LdStGeneral, []>; @@ -516,9 +532,9 @@ def STVEHX: XForm_8<31, 167, (ops VRRC:$rS, GPRC:$rA, GPRC:$rB), def STVEWX: XForm_8<31, 199, (ops VRRC:$rS, GPRC:$rA, GPRC:$rB), "stvewx $rS, $rA, $rB", LdStGeneral, []>; -def STVX : XForm_8<31, 231, (ops VRRC:$rS, GPRC:$rA, GPRC:$rB), - "stvx $rS, $rA, $rB", LdStGeneral, - []>; +def STVX : XForm_8<31, 231, (ops VRRC:$rS, memrr:$dst), + "stvx $rS, $dst", LdStGeneral, + [(store VRRC:$rS, xoaddr:$dst)]>; } def SRAWI : XForm_10<31, 824, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH), "srawi $rA, $rS, $SH", IntShift, @@ -555,12 +571,12 @@ def FCMPUD : XForm_17<63, 0, (ops CRRC:$crD, F8RC:$fA, F8RC:$fB), "fcmpu $crD, $fA, $fB", FPCompare>; let isLoad = 1 in { -def LFSX : XForm_25<31, 535, (ops F4RC:$dst, GPRC:$base, GPRC:$index), - "lfsx $dst, $base, $index", LdStLFDU, - []>; -def LFDX : XForm_25<31, 599, (ops F8RC:$dst, GPRC:$base, GPRC:$index), - "lfdx $dst, $base, $index", LdStLFDU, - []>; +def LFSX : XForm_25<31, 535, (ops F4RC:$frD, memrr:$src), + "lfsx $frD, $src", LdStLFDU, + [(set F4RC:$frD, (load xaddr:$src))]>; +def LFDX : XForm_25<31, 599, (ops F8RC:$frD, memrr:$src), + "lfdx $frD, $src", LdStLFDU, + [(set F8RC:$frD, (load xaddr:$src))]>; } def FCFID : XForm_26<63, 846, (ops F8RC:$frD, F8RC:$frB), "fcfid $frD, $frB", FPGeneral, @@ -614,12 +630,15 @@ def FNEGD : XForm_26<63, 40, (ops F8RC:$frD, F8RC:$frB), let isStore = 1 in { -def STFSX : XForm_28<31, 663, (ops F4RC:$frS, GPRC:$rA, GPRC:$rB), - "stfsx $frS, $rA, $rB", LdStUX, - []>; -def STFDX : XForm_28<31, 727, (ops F8RC:$frS, GPRC:$rA, GPRC:$rB), - "stfdx $frS, $rA, $rB", LdStUX, +def STFIWX: XForm_28<31, 983, (ops F4RC:$frS, memrr:$dst), + "stfiwx $frS, $dst", LdStUX, []>; +def STFSX : XForm_28<31, 663, (ops F4RC:$frS, memrr:$dst), + "stfsx $frS, $dst", LdStUX, + [(store F4RC:$frS, xaddr:$dst)]>; +def STFDX : XForm_28<31, 727, (ops F8RC:$frS, memrr:$dst), + "stfdx $frS, $dst", LdStUX, + [(store F8RC:$frS, xaddr:$dst)]>; } // XL-Form instructions. condition register logical ops. @@ -1012,6 +1031,27 @@ def : Pat<(srl GPRC:$rS, GPRC:$rB), def : Pat<(shl GPRC:$rS, GPRC:$rB), (SLW GPRC:$rS, GPRC:$rB)>; +def : Pat<(i32 (zextload iaddr:$src, i1)), + (LBZ iaddr:$src)>; +def : Pat<(i32 (zextload xaddr:$src, i1)), + (LBZX xaddr:$src)>; +def : Pat<(i32 (extload iaddr:$src, i1)), + (LBZ iaddr:$src)>; +def : Pat<(i32 (extload xaddr:$src, i1)), + (LBZX xaddr:$src)>; +def : Pat<(i32 (extload iaddr:$src, i8)), + (LBZ iaddr:$src)>; +def : Pat<(i32 (extload xaddr:$src, i8)), + (LBZX xaddr:$src)>; +def : Pat<(i32 (extload iaddr:$src, i16)), + (LHZ iaddr:$src)>; +def : Pat<(i32 (extload xaddr:$src, i16)), + (LHZX xaddr:$src)>; +def : Pat<(f64 (extload iaddr:$src, f32)), + (FMRSD (LFS iaddr:$src))>; +def : Pat<(f64 (extload xaddr:$src, f32)), + (FMRSD (LFSX xaddr:$src))>; + // Same as above, but using a temporary. FIXME: implement temporaries :) /* def : Pattern<(xor GPRC:$in, imm:$imm), -- 2.34.1