mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-30 06:40:53 +00:00
[MIPS GlobalISel] Select instructions to load and store i32 on stack
Add code for selection of G_LOAD, G_STORE, G_GEP, G_FRAMEINDEX and G_CONSTANT. Support loads and stores of i32 values. Patch by Petar Avramovic. Differential Revision: https://reviews.llvm.org/D48957 llvm-svn: 337168
This commit is contained in:
parent
66aa54677c
commit
fd9d371096
@ -107,8 +107,72 @@ bool MipsInstructionSelector::select(MachineInstr &I,
|
||||
if (selectImpl(I, CoverageInfo)) {
|
||||
return true;
|
||||
}
|
||||
// We didn't select anything.
|
||||
return false;
|
||||
|
||||
MachineInstr *MI = nullptr;
|
||||
using namespace TargetOpcode;
|
||||
|
||||
switch (I.getOpcode()) {
|
||||
case G_GEP: {
|
||||
MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
|
||||
.add(I.getOperand(0))
|
||||
.add(I.getOperand(1))
|
||||
.add(I.getOperand(2));
|
||||
break;
|
||||
}
|
||||
case G_FRAME_INDEX: {
|
||||
MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
|
||||
.add(I.getOperand(0))
|
||||
.add(I.getOperand(1))
|
||||
.addImm(0);
|
||||
break;
|
||||
}
|
||||
case G_STORE:
|
||||
case G_LOAD: {
|
||||
const unsigned DestReg = I.getOperand(0).getReg();
|
||||
const unsigned DestRegBank = RBI.getRegBank(DestReg, MRI, TRI)->getID();
|
||||
const unsigned OpSize = MRI.getType(DestReg).getSizeInBits();
|
||||
|
||||
if (DestRegBank != Mips::GPRBRegBankID || OpSize != 32)
|
||||
return false;
|
||||
|
||||
const unsigned NewOpc = I.getOpcode() == G_STORE ? Mips::SW : Mips::LW;
|
||||
|
||||
MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
|
||||
.add(I.getOperand(0))
|
||||
.add(I.getOperand(1))
|
||||
.addImm(0)
|
||||
.addMemOperand(*I.memoperands_begin());
|
||||
break;
|
||||
}
|
||||
case G_CONSTANT: {
|
||||
int Imm = I.getOperand(1).getCImm()->getValue().getLimitedValue();
|
||||
unsigned LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
|
||||
MachineInstr *LUi, *ORi;
|
||||
|
||||
LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
|
||||
.addDef(LUiReg)
|
||||
.addImm(Imm >> 16);
|
||||
|
||||
ORi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ORi))
|
||||
.addDef(I.getOperand(0).getReg())
|
||||
.addUse(LUiReg)
|
||||
.addImm(Imm & 0xFFFF);
|
||||
|
||||
if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
|
||||
return false;
|
||||
if (!constrainSelectedInstRegOperands(*ORi, TII, TRI, RBI))
|
||||
return false;
|
||||
|
||||
I.eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
I.eraseFromParent();
|
||||
return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
|
@ -20,9 +20,22 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
|
||||
using namespace TargetOpcode;
|
||||
|
||||
const LLT s32 = LLT::scalar(32);
|
||||
const LLT p0 = LLT::pointer(0, 32);
|
||||
|
||||
getActionDefinitionsBuilder(G_ADD).legalFor({s32});
|
||||
|
||||
getActionDefinitionsBuilder({G_LOAD, G_STORE})
|
||||
.legalFor({{s32, p0}});
|
||||
|
||||
getActionDefinitionsBuilder(G_CONSTANT)
|
||||
.legalFor({s32});
|
||||
|
||||
getActionDefinitionsBuilder(G_GEP)
|
||||
.legalFor({{p0, s32}});
|
||||
|
||||
getActionDefinitionsBuilder(G_FRAME_INDEX)
|
||||
.legalFor({p0});
|
||||
|
||||
computeTables();
|
||||
verify(*ST.getInstrInfo());
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass(
|
||||
case Mips::GPR32RegClassID:
|
||||
case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
|
||||
case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
|
||||
case Mips::SP32RegClassID:
|
||||
return getRegBank(Mips::GPRBRegBankID);
|
||||
default:
|
||||
llvm_unreachable("Register class not supported");
|
||||
@ -80,8 +81,16 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
|
||||
switch (Opc) {
|
||||
case G_ADD:
|
||||
case G_LOAD:
|
||||
case G_STORE:
|
||||
case G_GEP:
|
||||
OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
|
||||
break;
|
||||
case G_CONSTANT:
|
||||
case G_FRAME_INDEX:
|
||||
OperandsMapping =
|
||||
getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr});
|
||||
break;
|
||||
default:
|
||||
return getInvalidInstructionMapping();
|
||||
}
|
||||
|
@ -0,0 +1,65 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||
# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
|
||||
--- |
|
||||
|
||||
declare i32 @f(i32, i32, i32, i32, i32)
|
||||
define void @g(i32, i32, i32, i32, i32) {entry: ret void}
|
||||
|
||||
...
|
||||
---
|
||||
name: g
|
||||
alignment: 2
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
tracksRegLiveness: true
|
||||
fixedStack:
|
||||
- { id: 0, offset: 16, size: 4, alignment: 8, stack-id: 0, isImmutable: true }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
liveins: $a0, $a1, $a2, $a3
|
||||
|
||||
; MIPS32-LABEL: name: g
|
||||
; MIPS32: liveins: $a0, $a1, $a2, $a3
|
||||
; MIPS32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
|
||||
; MIPS32: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
|
||||
; MIPS32: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
|
||||
; MIPS32: [[COPY3:%[0-9]+]]:gpr32 = COPY $a3
|
||||
; MIPS32: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu %fixed-stack.0, 0
|
||||
; MIPS32: [[LW:%[0-9]+]]:gpr32 = LW [[ADDiu]], 0 :: (load 4 from %fixed-stack.0, align 0)
|
||||
; MIPS32: ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
||||
; MIPS32: $a0 = COPY [[COPY]]
|
||||
; MIPS32: $a1 = COPY [[COPY1]]
|
||||
; MIPS32: $a2 = COPY [[COPY2]]
|
||||
; MIPS32: $a3 = COPY [[COPY3]]
|
||||
; MIPS32: [[COPY4:%[0-9]+]]:gpr32 = COPY $sp
|
||||
; MIPS32: [[LUi:%[0-9]+]]:gpr32 = LUi 0
|
||||
; MIPS32: [[ORi:%[0-9]+]]:gpr32 = ORi [[LUi]], 16
|
||||
; MIPS32: [[ADDu:%[0-9]+]]:gpr32 = ADDu [[COPY4]], [[ORi]]
|
||||
; MIPS32: SW [[LW]], [[ADDu]], 0 :: (store 4 into stack + 16, align 0)
|
||||
; MIPS32: JAL @f, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
||||
; MIPS32: [[COPY5:%[0-9]+]]:gpr32 = COPY $v0
|
||||
; MIPS32: ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
||||
; MIPS32: $v0 = COPY [[COPY5]]
|
||||
; MIPS32: RetRA implicit $v0
|
||||
%0:gprb(s32) = COPY $a0
|
||||
%1:gprb(s32) = COPY $a1
|
||||
%2:gprb(s32) = COPY $a2
|
||||
%3:gprb(s32) = COPY $a3
|
||||
%5:gprb(p0) = G_FRAME_INDEX %fixed-stack.0
|
||||
%4:gprb(s32) = G_LOAD %5(p0) :: (load 4 from %fixed-stack.0, align 0)
|
||||
ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
||||
$a0 = COPY %0(s32)
|
||||
$a1 = COPY %1(s32)
|
||||
$a2 = COPY %2(s32)
|
||||
$a3 = COPY %3(s32)
|
||||
%7:gprb(p0) = COPY $sp
|
||||
%8:gprb(s32) = G_CONSTANT i32 16
|
||||
%9:gprb(p0) = G_GEP %7, %8(s32)
|
||||
G_STORE %4(s32), %9(p0) :: (store 4 into stack + 16, align 0)
|
||||
JAL @f, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
||||
%6:gprb(s32) = COPY $v0
|
||||
ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
||||
$v0 = COPY %6(s32)
|
||||
RetRA implicit $v0
|
||||
|
||||
...
|
62
test/CodeGen/Mips/GlobalISel/legalizer/stack_args.mir
Normal file
62
test/CodeGen/Mips/GlobalISel/legalizer/stack_args.mir
Normal file
@ -0,0 +1,62 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||
# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
|
||||
--- |
|
||||
|
||||
declare i32 @f(i32, i32, i32, i32, i32)
|
||||
define void @g(i32, i32, i32, i32, i32) {entry: ret void}
|
||||
|
||||
...
|
||||
---
|
||||
name: g
|
||||
alignment: 2
|
||||
tracksRegLiveness: true
|
||||
fixedStack:
|
||||
- { id: 0, offset: 16, size: 4, alignment: 8, stack-id: 0, isImmutable: true }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
liveins: $a0, $a1, $a2, $a3
|
||||
|
||||
; MIPS32-LABEL: name: g
|
||||
; MIPS32: liveins: $a0, $a1, $a2, $a3
|
||||
; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
||||
; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
|
||||
; MIPS32: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
|
||||
; MIPS32: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
|
||||
; MIPS32: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
||||
; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %fixed-stack.0, align 0)
|
||||
; MIPS32: ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
||||
; MIPS32: $a0 = COPY [[COPY]](s32)
|
||||
; MIPS32: $a1 = COPY [[COPY1]](s32)
|
||||
; MIPS32: $a2 = COPY [[COPY2]](s32)
|
||||
; MIPS32: $a3 = COPY [[COPY3]](s32)
|
||||
; MIPS32: [[COPY4:%[0-9]+]]:_(p0) = COPY $sp
|
||||
; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
|
||||
; MIPS32: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[COPY4]], [[C]](s32)
|
||||
; MIPS32: G_STORE [[LOAD]](s32), [[GEP]](p0) :: (store 4 into stack + 16, align 0)
|
||||
; MIPS32: JAL @f, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
||||
; MIPS32: [[COPY5:%[0-9]+]]:_(s32) = COPY $v0
|
||||
; MIPS32: ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
||||
; MIPS32: $v0 = COPY [[COPY5]](s32)
|
||||
; MIPS32: RetRA implicit $v0
|
||||
%0:_(s32) = COPY $a0
|
||||
%1:_(s32) = COPY $a1
|
||||
%2:_(s32) = COPY $a2
|
||||
%3:_(s32) = COPY $a3
|
||||
%5:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
||||
%4:_(s32) = G_LOAD %5(p0) :: (load 4 from %fixed-stack.0, align 0)
|
||||
ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
||||
$a0 = COPY %0(s32)
|
||||
$a1 = COPY %1(s32)
|
||||
$a2 = COPY %2(s32)
|
||||
$a3 = COPY %3(s32)
|
||||
%7:_(p0) = COPY $sp
|
||||
%8:_(s32) = G_CONSTANT i32 16
|
||||
%9:_(p0) = G_GEP %7, %8(s32)
|
||||
G_STORE %4(s32), %9(p0) :: (store 4 into stack + 16, align 0)
|
||||
JAL @f, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
||||
%6:_(s32) = COPY $v0
|
||||
ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
||||
$v0 = COPY %6(s32)
|
||||
RetRA implicit $v0
|
||||
|
||||
...
|
29
test/CodeGen/Mips/GlobalISel/llvm-ir/stack_args.ll
Normal file
29
test/CodeGen/Mips/GlobalISel/llvm-ir/stack_args.ll
Normal file
@ -0,0 +1,29 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=MIPS32
|
||||
|
||||
declare i32 @f(i32, i32, i32, i32, i32)
|
||||
|
||||
define i32 @g(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5){
|
||||
; MIPS32-LABEL: g:
|
||||
; MIPS32: # %bb.0: # %entry
|
||||
; MIPS32-NEXT: addiu $sp, $sp, -32
|
||||
; MIPS32-NEXT: .cfi_def_cfa_offset 32
|
||||
; MIPS32-NEXT: sw $ra, 28($sp) # 4-byte Folded Spill
|
||||
; MIPS32-NEXT: .cfi_offset 31, -4
|
||||
; MIPS32-NEXT: addiu $1, $sp, 48
|
||||
; MIPS32-NEXT: lw $1, 0($1)
|
||||
; MIPS32-NEXT: move $2, $sp
|
||||
; MIPS32-NEXT: lui $3, 0
|
||||
; MIPS32-NEXT: ori $3, $3, 16
|
||||
; MIPS32-NEXT: addu $2, $2, $3
|
||||
; MIPS32-NEXT: sw $1, 0($2)
|
||||
; MIPS32-NEXT: jal f
|
||||
; MIPS32-NEXT: nop
|
||||
; MIPS32-NEXT: lw $ra, 28($sp) # 4-byte Folded Reload
|
||||
; MIPS32-NEXT: addiu $sp, $sp, 32
|
||||
; MIPS32-NEXT: jr $ra
|
||||
; MIPS32-NEXT: nop
|
||||
entry:
|
||||
%call = call i32 @f(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5)
|
||||
ret i32 %call
|
||||
}
|
63
test/CodeGen/Mips/GlobalISel/regbankselect/stack_args.mir
Normal file
63
test/CodeGen/Mips/GlobalISel/regbankselect/stack_args.mir
Normal file
@ -0,0 +1,63 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||
# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=regbankselect -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
|
||||
--- |
|
||||
|
||||
declare i32 @f(i32, i32, i32, i32, i32)
|
||||
define void @g(i32, i32, i32, i32, i32) {entry: ret void}
|
||||
|
||||
...
|
||||
---
|
||||
name: g
|
||||
alignment: 2
|
||||
legalized: true
|
||||
tracksRegLiveness: true
|
||||
fixedStack:
|
||||
- { id: 0, offset: 16, size: 4, alignment: 8, stack-id: 0, isImmutable: true }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
liveins: $a0, $a1, $a2, $a3
|
||||
|
||||
; MIPS32-LABEL: name: g
|
||||
; MIPS32: liveins: $a0, $a1, $a2, $a3
|
||||
; MIPS32: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
|
||||
; MIPS32: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $a1
|
||||
; MIPS32: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $a2
|
||||
; MIPS32: [[COPY3:%[0-9]+]]:gprb(s32) = COPY $a3
|
||||
; MIPS32: [[FRAME_INDEX:%[0-9]+]]:gprb(p0) = G_FRAME_INDEX %fixed-stack.0
|
||||
; MIPS32: [[LOAD:%[0-9]+]]:gprb(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %fixed-stack.0, align 0)
|
||||
; MIPS32: ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
||||
; MIPS32: $a0 = COPY [[COPY]](s32)
|
||||
; MIPS32: $a1 = COPY [[COPY1]](s32)
|
||||
; MIPS32: $a2 = COPY [[COPY2]](s32)
|
||||
; MIPS32: $a3 = COPY [[COPY3]](s32)
|
||||
; MIPS32: [[COPY4:%[0-9]+]]:gprb(p0) = COPY $sp
|
||||
; MIPS32: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 16
|
||||
; MIPS32: [[GEP:%[0-9]+]]:gprb(p0) = G_GEP [[COPY4]], [[C]](s32)
|
||||
; MIPS32: G_STORE [[LOAD]](s32), [[GEP]](p0) :: (store 4 into stack + 16, align 0)
|
||||
; MIPS32: JAL @f, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
||||
; MIPS32: [[COPY5:%[0-9]+]]:gprb(s32) = COPY $v0
|
||||
; MIPS32: ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
||||
; MIPS32: $v0 = COPY [[COPY5]](s32)
|
||||
; MIPS32: RetRA implicit $v0
|
||||
%0:_(s32) = COPY $a0
|
||||
%1:_(s32) = COPY $a1
|
||||
%2:_(s32) = COPY $a2
|
||||
%3:_(s32) = COPY $a3
|
||||
%5:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
||||
%4:_(s32) = G_LOAD %5(p0) :: (load 4 from %fixed-stack.0, align 0)
|
||||
ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
||||
$a0 = COPY %0(s32)
|
||||
$a1 = COPY %1(s32)
|
||||
$a2 = COPY %2(s32)
|
||||
$a3 = COPY %3(s32)
|
||||
%7:_(p0) = COPY $sp
|
||||
%8:_(s32) = G_CONSTANT i32 16
|
||||
%9:_(p0) = G_GEP %7, %8(s32)
|
||||
G_STORE %4(s32), %9(p0) :: (store 4 into stack + 16, align 0)
|
||||
JAL @f, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
||||
%6:_(s32) = COPY $v0
|
||||
ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
||||
$v0 = COPY %6(s32)
|
||||
RetRA implicit $v0
|
||||
|
||||
...
|
Loading…
Reference in New Issue
Block a user