Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 8b3a8d6

Browse files
author
Reed Kotler
committed
Add load/store functionality
Summary: This patches allows non conversions like i1=i2; where both are global ints. In addition, arithmetic and other things start to work since fast-isel will use existing patterns for non fast-isel from tablegen files where applicable. In addition i8, i16 will work in this limited context for assignment without the need for sign extension (zero or signed). It does not matter how i8 or i16 are loaded (zero or sign extended) since only the 8 or 16 relevant bits are used and clang will ask for sign extension before using them in arithmetic. This is all made more complete in forthcoming patches. for example: int i, j=1, k=3; void foo() { i = j + k; } Keep in mind that this pass is not enabled right now and is an experimental pass It can only be enabled with a hidden option to llvm of -mips-fast-isel. Test Plan: Run test-suite, loadstore2.ll and I will run some executable tests. Reviewers: dsanders Subscribers: mcrosier Differential Revision: http://reviews.llvm.org/D3856 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211061 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 44d2cdc commit 8b3a8d6

File tree

2 files changed

+176
-7
lines changed

2 files changed

+176
-7
lines changed

lib/Target/Mips/MipsFastISel.cpp

Lines changed: 93 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,11 @@ class MipsFastISel final : public FastISel {
6969
bool ComputeAddress(const Value *Obj, Address &Addr);
7070

7171
private:
72+
bool EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
73+
unsigned Alignment = 0);
7274
bool EmitStore(MVT VT, unsigned SrcReg, Address &Addr,
7375
unsigned Alignment = 0);
76+
bool SelectLoad(const Instruction *I);
7477
bool SelectRet(const Instruction *I);
7578
bool SelectStore(const Instruction *I);
7679

@@ -105,6 +108,11 @@ class MipsFastISel final : public FastISel {
105108
return EmitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset);
106109
}
107110

111+
MachineInstrBuilder EmitInstLoad(unsigned Opc, unsigned DstReg,
112+
unsigned MemReg, int64_t MemOffset) {
113+
return EmitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);
114+
}
115+
108116
#include "MipsGenFastISel.inc"
109117
};
110118

@@ -126,6 +134,8 @@ bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
126134
// We will extend this in a later patch:
127135
// If this is a type than can be sign or zero-extended to a basic operation
128136
// go ahead and accept it now.
137+
if (VT == MVT::i8 || VT == MVT::i16)
138+
return true;
129139
return false;
130140
}
131141

@@ -142,6 +152,45 @@ bool MipsFastISel::ComputeAddress(const Value *Obj, Address &Addr) {
142152
return Addr.Base.Reg != 0;
143153
}
144154

155+
bool MipsFastISel::EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
156+
unsigned Alignment) {
157+
//
158+
// more cases will be handled here in following patches.
159+
//
160+
unsigned Opc;
161+
switch (VT.SimpleTy) {
162+
case MVT::i32: {
163+
ResultReg = createResultReg(&Mips::GPR32RegClass);
164+
Opc = Mips::LW;
165+
break;
166+
}
167+
case MVT::i16: {
168+
ResultReg = createResultReg(&Mips::GPR32RegClass);
169+
Opc = Mips::LHu;
170+
break;
171+
}
172+
case MVT::i8: {
173+
ResultReg = createResultReg(&Mips::GPR32RegClass);
174+
Opc = Mips::LBu;
175+
break;
176+
}
177+
case MVT::f32: {
178+
ResultReg = createResultReg(&Mips::FGR32RegClass);
179+
Opc = Mips::LWC1;
180+
break;
181+
}
182+
case MVT::f64: {
183+
ResultReg = createResultReg(&Mips::AFGR64RegClass);
184+
Opc = Mips::LDC1;
185+
break;
186+
}
187+
default:
188+
return false;
189+
}
190+
EmitInstLoad(Opc, ResultReg, Addr.Base.Reg, Addr.Offset);
191+
return true;
192+
}
193+
145194
// Materialize a constant into a register, and return the register
146195
// number (or zero if we failed to handle it).
147196
unsigned MipsFastISel::TargetMaterializeConstant(const Constant *C) {
@@ -167,14 +216,49 @@ bool MipsFastISel::EmitStore(MVT VT, unsigned SrcReg, Address &Addr,
167216
//
168217
// more cases will be handled here in following patches.
169218
//
170-
if (VT == MVT::i32)
171-
EmitInstStore(Mips::SW, SrcReg, Addr.Base.Reg, Addr.Offset);
172-
else if (VT == MVT::f32)
173-
EmitInstStore(Mips::SWC1, SrcReg, Addr.Base.Reg, Addr.Offset);
174-
else if (VT == MVT::f64)
175-
EmitInstStore(Mips::SDC1, SrcReg, Addr.Base.Reg, Addr.Offset);
176-
else
219+
unsigned Opc;
220+
switch (VT.SimpleTy) {
221+
case MVT::i8:
222+
Opc = Mips::SB;
223+
break;
224+
case MVT::i16:
225+
Opc = Mips::SH;
226+
break;
227+
case MVT::i32:
228+
Opc = Mips::SW;
229+
break;
230+
case MVT::f32:
231+
Opc = Mips::SWC1;
232+
break;
233+
case MVT::f64:
234+
Opc = Mips::SDC1;
235+
break;
236+
default:
237+
return false;
238+
}
239+
EmitInstStore(Opc, SrcReg, Addr.Base.Reg, Addr.Offset);
240+
return true;
241+
}
242+
243+
bool MipsFastISel::SelectLoad(const Instruction *I) {
244+
// Atomic loads need special handling.
245+
if (cast<LoadInst>(I)->isAtomic())
246+
return false;
247+
248+
// Verify we have a legal type before going any further.
249+
MVT VT;
250+
if (!isLoadTypeLegal(I->getType(), VT))
251+
return false;
252+
253+
// See if we can handle this address.
254+
Address Addr;
255+
if (!ComputeAddress(I->getOperand(0), Addr))
256+
return false;
257+
258+
unsigned ResultReg;
259+
if (!EmitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment()))
177260
return false;
261+
UpdateValueMap(I, ResultReg);
178262
return true;
179263
}
180264

@@ -224,6 +308,8 @@ bool MipsFastISel::TargetSelectInstruction(const Instruction *I) {
224308
switch (I->getOpcode()) {
225309
default:
226310
break;
311+
case Instruction::Load:
312+
return SelectLoad(I);
227313
case Instruction::Store:
228314
return SelectStore(I);
229315
case Instruction::Ret:
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
; ModuleID = 'loadstore2.c'
2+
target datalayout = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
3+
target triple = "mips--linux-gnu"
4+
5+
@c2 = common global i8 0, align 1
6+
@c1 = common global i8 0, align 1
7+
; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \
8+
; RUN: < %s | FileCheck %s
9+
10+
@s2 = common global i16 0, align 2
11+
@s1 = common global i16 0, align 2
12+
@i2 = common global i32 0, align 4
13+
@i1 = common global i32 0, align 4
14+
@f2 = common global float 0.000000e+00, align 4
15+
@f1 = common global float 0.000000e+00, align 4
16+
@d2 = common global double 0.000000e+00, align 8
17+
@d1 = common global double 0.000000e+00, align 8
18+
19+
; Function Attrs: nounwind
20+
define void @cfoo() #0 {
21+
entry:
22+
%0 = load i8* @c2, align 1
23+
store i8 %0, i8* @c1, align 1
24+
; CHECK-LABEL: cfoo:
25+
; CHECK: lbu $[[REGc:[0-9]+]], 0(${{[0-9]+}})
26+
; CHECK: sb $[[REGc]], 0(${{[0-9]+}})
27+
28+
29+
ret void
30+
}
31+
32+
; Function Attrs: nounwind
33+
define void @sfoo() #0 {
34+
entry:
35+
%0 = load i16* @s2, align 2
36+
store i16 %0, i16* @s1, align 2
37+
; CHECK-LABEL: sfoo:
38+
; CHECK: lhu $[[REGs:[0-9]+]], 0(${{[0-9]+}})
39+
; CHECK: sh $[[REGs]], 0(${{[0-9]+}})
40+
41+
ret void
42+
}
43+
44+
; Function Attrs: nounwind
45+
define void @ifoo() #0 {
46+
entry:
47+
%0 = load i32* @i2, align 4
48+
store i32 %0, i32* @i1, align 4
49+
; CHECK-LABEL: ifoo:
50+
; CHECK: lw $[[REGi:[0-9]+]], 0(${{[0-9]+}})
51+
; CHECK: sw $[[REGi]], 0(${{[0-9]+}})
52+
53+
ret void
54+
}
55+
56+
; Function Attrs: nounwind
57+
define void @ffoo() #0 {
58+
entry:
59+
%0 = load float* @f2, align 4
60+
store float %0, float* @f1, align 4
61+
; CHECK-LABEL: ffoo:
62+
; CHECK: lwc1 $f[[REGf:[0-9]+]], 0(${{[0-9]+}})
63+
; CHECK: swc1 $f[[REGf]], 0(${{[0-9]+}})
64+
65+
66+
ret void
67+
}
68+
69+
; Function Attrs: nounwind
70+
define void @dfoo() #0 {
71+
entry:
72+
%0 = load double* @d2, align 8
73+
store double %0, double* @d1, align 8
74+
; CHECK-LABEL: dfoo:
75+
; CHECK: ldc1 $f[[REGd:[0-9]+]], 0(${{[0-9]+}})
76+
; CHECK: sdc1 $f[[REGd]], 0(${{[0-9]+}})
77+
; CHECK: .end dfoo
78+
ret void
79+
}
80+
81+
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
82+
83+

0 commit comments

Comments
 (0)