llvm.org GIT mirror llvm / cb518ee
Add patterns for unaligned load and store instructions and enable the instruction selector to generate them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141471 91177308-0d34-0410-b5e6-96231b3b80d8 Akira Hatanaka 8 years ago
2 changed file(s) with 77 addition(s) and 47 deletion(s). Raw diff Collapse all Expand all
4343
4444 using namespace llvm;
4545
46 static bool isUnalignedLoadStore(unsigned Opc) {
47 return Opc == Mips::ULW || Opc == Mips::ULH || Opc == Mips::ULHu ||
48 Opc == Mips::USW || Opc == Mips::USH;
49 }
50
4651 void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
4752 SmallString<128> Str;
4853 raw_svector_ostream OS(Str);
5762 MCInst TmpInst0;
5863 MCInstLowering.Lower(MI, TmpInst0);
5964
60 // Convert aligned loads/stores to their unaligned counterparts.
61 if (!MI->memoperands_empty()) {
62 unsigned NaturalAlignment, UnalignedOpc;
63
64 switch (Opc) {
65 case Mips::LW: NaturalAlignment = 4; UnalignedOpc = Mips::ULW; break;
66 case Mips::SW: NaturalAlignment = 4; UnalignedOpc = Mips::USW; break;
67 case Mips::LH: NaturalAlignment = 2; UnalignedOpc = Mips::ULH; break;
68 case Mips::LHu: NaturalAlignment = 2; UnalignedOpc = Mips::ULHu; break;
69 case Mips::SH: NaturalAlignment = 2; UnalignedOpc = Mips::USH; break;
70 default: NaturalAlignment = 0;
71 }
72
73 if ((*MI->memoperands_begin())->getAlignment() < NaturalAlignment) {
74 MCInst Directive;
75 Directive.setOpcode(Mips::MACRO);
76 OutStreamer.EmitInstruction(Directive);
77 TmpInst0.setOpcode(UnalignedOpc);
78 OutStreamer.EmitInstruction(TmpInst0);
79 Directive.setOpcode(Mips::NOMACRO);
80 OutStreamer.EmitInstruction(Directive);
81 return;
82 }
65 // Enclose unaligned load or store with .macro & .nomacro directives.
66 if (isUnalignedLoadStore(Opc)) {
67 MCInst Directive;
68 Directive.setOpcode(Mips::MACRO);
69 OutStreamer.EmitInstruction(Directive);
70 OutStreamer.EmitInstruction(TmpInst0);
71 Directive.setOpcode(Mips::NOMACRO);
72 OutStreamer.EmitInstruction(Directive);
73 return;
8374 }
8475
8576 OutStreamer.EmitInstruction(TmpInst0);
188188 def addr : ComplexPattern;
189189
190190 //===----------------------------------------------------------------------===//
191 // Pattern fragment for load/store
192 //===----------------------------------------------------------------------===//
193 class UnalignedLoad : PatFrag<(ops node:$ptr), (Node node:$ptr), [{
194 LoadSDNode *LD = cast(N);
195 return LD->getMemoryVT().getSizeInBits()/8 > LD->getAlignment();
196 }]>;
197
198 class AlignedLoad : PatFrag<(ops node:$ptr), (Node node:$ptr), [{
199 LoadSDNode *LD = cast(N);
200 return LD->getMemoryVT().getSizeInBits()/8 <= LD->getAlignment();
201 }]>;
202
203 class UnalignedStore : PatFrag<(ops node:$val, node:$ptr),
204 (Node node:$val, node:$ptr), [{
205 StoreSDNode *SD = cast(N);
206 return SD->getMemoryVT().getSizeInBits()/8 > SD->getAlignment();
207 }]>;
208
209 class AlignedStore : PatFrag<(ops node:$val, node:$ptr),
210 (Node node:$val, node:$ptr), [{
211 StoreSDNode *SD = cast(N);
212 return SD->getMemoryVT().getSizeInBits()/8 <= SD->getAlignment();
213 }]>;
214
215 // Load/Store PatFrags.
216 def sextloadi16_a : AlignedLoad;
217 def zextloadi16_a : AlignedLoad;
218 def extloadi16_a : AlignedLoad;
219 def load_a : AlignedLoad;
220 def truncstorei16_a : AlignedStore;
221 def store_a : AlignedStore;
222 def sextloadi16_u : UnalignedLoad;
223 def zextloadi16_u : UnalignedLoad;
224 def extloadi16_u : UnalignedLoad;
225 def load_u : UnalignedLoad;
226 def truncstorei16_u : UnalignedStore;
227 def store_u : UnalignedStore;
228
229 //===----------------------------------------------------------------------===//
191230 // Instructions specific format
192231 //===----------------------------------------------------------------------===//
193232
273312
274313 // Memory Load/Store
275314 let canFoldAsLoad = 1 in
276 class LoadM op, string instr_asm, PatFrag OpNode>:
315 class LoadM op, string instr_asm, PatFrag OpNode, bit Pseudo = 0>:
277316 FI
278317 !strconcat(instr_asm, "\t$dst, $addr"),
279 [(set CPURegs:$dst, (OpNode addr:$addr))], IILoad>;
280
281 class StoreM op, string instr_asm, PatFrag OpNode>:
318 [(set CPURegs:$dst, (OpNode addr:$addr))], IILoad> {
319 let isPseudo = Pseudo;
320 }
321
322 class StoreM op, string instr_asm, PatFrag OpNode, bit Pseudo = 0>:
282323 FI
283324 !strconcat(instr_asm, "\t$dst, $addr"),
284 [(OpNode CPURegs:$dst, addr:$addr)], IIStore>;
325 [(OpNode CPURegs:$dst, addr:$addr)], IIStore> {
326 let isPseudo = Pseudo;
327 }
285328
286329 // Conditional Branch
287330 let isBranch = 1, isTerminator=1, hasDelaySlot = 1 in {
497540 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap;
498541 }
499542
500 // Unaligned loads and stores.
501 // Replaces LW or SW during MCInstLowering if memory access is unaligned.
502 def ULW :
503 MipsPseudo<(outs CPURegs:$dst), (ins mem:$addr), "ulw\t$dst, $addr", []>;
504 def ULH :
505 MipsPseudo<(outs CPURegs:$dst), (ins mem:$addr), "ulh\t$dst, $addr", []>;
506 def ULHu :
507 MipsPseudo<(outs CPURegs:$dst), (ins mem:$addr), "ulhu\t$dst, $addr", []>;
508 def USW :
509 MipsPseudo<(outs), (ins CPURegs:$dst, mem:$addr), "usw\t$dst, $addr", []>;
510 def USH :
511 MipsPseudo<(outs), (ins CPURegs:$dst, mem:$addr), "ush\t$dst, $addr", []>;
512
513543 //===----------------------------------------------------------------------===//
514544 // Instruction definition
515545 //===----------------------------------------------------------------------===//
555585 }
556586
557587 /// Load and Store Instructions
588 /// aligned
558589 def LB : LoadM<0x20, "lb", sextloadi8>;
559590 def LBu : LoadM<0x24, "lbu", zextloadi8>;
560 def LH : LoadM<0x21, "lh", sextloadi16>;
561 def LHu : LoadM<0x25, "lhu", zextloadi16>;
562 def LW : LoadM<0x23, "lw", load>;
591 def LH : LoadM<0x21, "lh", sextloadi16_a>;
592 def LHu : LoadM<0x25, "lhu", zextloadi16_a>;
593 def LW : LoadM<0x23, "lw", load_a>;
563594 def SB : StoreM<0x28, "sb", truncstorei8>;
564 def SH : StoreM<0x29, "sh", truncstorei16>;
565 def SW : StoreM<0x2b, "sw", store>;
595 def SH : StoreM<0x29, "sh", truncstorei16_a>;
596 def SW : StoreM<0x2b, "sw", store_a>;
597
598 /// unaligned
599 def ULH : LoadM<0x21, "ulh", sextloadi16_u, 1>;
600 def ULHu : LoadM<0x25, "ulhu", zextloadi16_u, 1>;
601 def ULW : LoadM<0x23, "ulw", load_u, 1>;
602 def USH : StoreM<0x29, "ush", truncstorei16_u, 1>;
603 def USW : StoreM<0x2b, "usw", store_u, 1>;
566604
567605 let hasSideEffects = 1 in
568606 def SYNC : MipsInst<(outs), (ins i32imm:$stype), "sync $stype",
788826 // extended load and stores
789827 def : Pat<(extloadi1 addr:$src), (LBu addr:$src)>;
790828 def : Pat<(extloadi8 addr:$src), (LBu addr:$src)>;
791 def : Pat<(extloadi16 addr:$src), (LHu addr:$src)>;
829 def : Pat<(extloadi16_a addr:$src), (LHu addr:$src)>;
830 def : Pat<(extloadi16_u addr:$src), (ULHu addr:$src)>;
792831
793832 // peepholes
794833 def : Pat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;