@@ -29,19 +29,148 @@ using namespace llvm;
29
29
ARMCallLowering::ARMCallLowering (const ARMTargetLowering &TLI)
30
30
: CallLowering(&TLI) {}
31
31
32
+ static bool isSupportedType (const DataLayout DL, const ARMTargetLowering &TLI,
33
+ Type *T) {
34
+ EVT VT = TLI.getValueType (DL, T);
35
+ return VT.isSimple () && VT.isInteger () &&
36
+ VT.getSimpleVT ().getSizeInBits () == 32 ;
37
+ }
38
+
39
+ namespace {
40
+ struct FuncReturnHandler : public CallLowering ::ValueHandler {
41
+ FuncReturnHandler (MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
42
+ MachineInstrBuilder &MIB)
43
+ : ValueHandler(MIRBuilder, MRI), MIB(MIB) {}
44
+
45
+ unsigned getStackAddress (uint64_t Size , int64_t Offset,
46
+ MachinePointerInfo &MPO) override {
47
+ llvm_unreachable (" Don't know how to get a stack address yet" );
48
+ }
49
+
50
+ void assignValueToReg (unsigned ValVReg, unsigned PhysReg,
51
+ CCValAssign &VA) override {
52
+ assert (VA.isRegLoc () && " Value shouldn't be assigned to reg" );
53
+ assert (VA.getLocReg () == PhysReg && " Assigning to the wrong reg?" );
54
+
55
+ assert (VA.getValVT ().getSizeInBits () == 32 && " Unsupported value size" );
56
+ assert (VA.getLocVT ().getSizeInBits () == 32 && " Unsupported location size" );
57
+
58
+ MIRBuilder.buildCopy (PhysReg, ValVReg);
59
+ MIB.addUse (PhysReg, RegState::Implicit);
60
+ }
61
+
62
+ void assignValueToAddress (unsigned ValVReg, unsigned Addr, uint64_t Size ,
63
+ MachinePointerInfo &MPO, CCValAssign &VA) override {
64
+ llvm_unreachable (" Don't know how to assign a value to an address yet" );
65
+ }
66
+
67
+ MachineInstrBuilder &MIB;
68
+ };
69
+ } // End anonymous namespace.
70
+
71
+ // / Lower the return value for the already existing \p Ret. This assumes that
72
+ // / \p MIRBuilder's insertion point is correct.
73
+ bool ARMCallLowering::lowerReturnVal (MachineIRBuilder &MIRBuilder,
74
+ const Value *Val, unsigned VReg,
75
+ MachineInstrBuilder &Ret) const {
76
+ if (!Val)
77
+ // Nothing to do here.
78
+ return true ;
79
+
80
+ auto &MF = MIRBuilder.getMF ();
81
+ const auto &F = *MF.getFunction ();
82
+
83
+ auto DL = MF.getDataLayout ();
84
+ auto &TLI = *getTLI<ARMTargetLowering>();
85
+ if (!isSupportedType (DL, TLI, Val->getType ()))
86
+ return false ;
87
+
88
+ CCAssignFn *AssignFn =
89
+ TLI.CCAssignFnForReturn (F.getCallingConv (), F.isVarArg ());
90
+
91
+ ArgInfo RetInfo (VReg, Val->getType ());
92
+ setArgFlags (RetInfo, AttributeSet::ReturnIndex, DL, F);
93
+
94
+ FuncReturnHandler RetHandler (MIRBuilder, MF.getRegInfo (), Ret);
95
+ return handleAssignments (MIRBuilder, AssignFn, RetInfo, RetHandler);
96
+ }
97
+
32
98
bool ARMCallLowering::lowerReturn (MachineIRBuilder &MIRBuilder,
33
99
const Value *Val, unsigned VReg) const {
34
- // We're currently only handling void returns
35
- if (Val != nullptr )
36
- return false ;
100
+ assert (!Val == !VReg && " Return value without a vreg" );
37
101
38
- AddDefaultPred (MIRBuilder.buildInstr (ARM::BX_RET));
102
+ auto Ret = AddDefaultPred (MIRBuilder.buildInstrNoInsert (ARM::BX_RET));
39
103
104
+ if (!lowerReturnVal (MIRBuilder, Val, VReg, Ret))
105
+ return false ;
106
+
107
+ MIRBuilder.insertInstr (Ret);
40
108
return true ;
41
109
}
42
110
111
+ namespace {
112
+ struct FormalArgHandler : public CallLowering ::ValueHandler {
113
+ FormalArgHandler (MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
114
+ : ValueHandler(MIRBuilder, MRI) {}
115
+
116
+ unsigned getStackAddress (uint64_t Size , int64_t Offset,
117
+ MachinePointerInfo &MPO) override {
118
+ llvm_unreachable (" Don't know how to get a stack address yet" );
119
+ }
120
+
121
+ void assignValueToReg (unsigned ValVReg, unsigned PhysReg,
122
+ CCValAssign &VA) override {
123
+ assert (VA.isRegLoc () && " Value shouldn't be assigned to reg" );
124
+ assert (VA.getLocReg () == PhysReg && " Assigning to the wrong reg?" );
125
+
126
+ assert (VA.getValVT ().getSizeInBits () == 32 && " Unsupported value size" );
127
+ assert (VA.getLocVT ().getSizeInBits () == 32 && " Unsupported location size" );
128
+
129
+ MIRBuilder.getMBB ().addLiveIn (PhysReg);
130
+ MIRBuilder.buildCopy (ValVReg, PhysReg);
131
+ }
132
+
133
+ void assignValueToAddress (unsigned ValVReg, unsigned Addr, uint64_t Size ,
134
+ MachinePointerInfo &MPO, CCValAssign &VA) override {
135
+ llvm_unreachable (" Don't know how to assign a value to an address yet" );
136
+ }
137
+ };
138
+ } // End anonymous namespace
139
+
43
140
bool ARMCallLowering::lowerFormalArguments (MachineIRBuilder &MIRBuilder,
44
141
const Function &F,
45
142
ArrayRef<unsigned > VRegs) const {
46
- return F.arg_empty ();
143
+ // Quick exit if there aren't any args
144
+ if (F.arg_empty ())
145
+ return true ;
146
+
147
+ // Stick to only 4 arguments for now
148
+ if (F.arg_size () > 4 )
149
+ return false ;
150
+
151
+ if (F.isVarArg ())
152
+ return false ;
153
+
154
+ auto DL = MIRBuilder.getMF ().getDataLayout ();
155
+ auto &TLI = *getTLI<ARMTargetLowering>();
156
+
157
+ auto &Args = F.getArgumentList ();
158
+ for (auto &Arg : Args)
159
+ if (!isSupportedType (DL, TLI, Arg.getType ()))
160
+ return false ;
161
+
162
+ CCAssignFn *AssignFn =
163
+ TLI.CCAssignFnForCall (F.getCallingConv (), F.isVarArg ());
164
+
165
+ SmallVector<ArgInfo, 8 > ArgInfos;
166
+ unsigned Idx = 0 ;
167
+ for (auto &Arg : Args) {
168
+ ArgInfo AInfo (VRegs[Idx], Arg.getType ());
169
+ setArgFlags (AInfo, Idx + 1 , DL, F);
170
+ ArgInfos.push_back (AInfo);
171
+ Idx++;
172
+ }
173
+
174
+ FormalArgHandler ArgHandler (MIRBuilder, MIRBuilder.getMF ().getRegInfo ());
175
+ return handleAssignments (MIRBuilder, AssignFn, ArgInfos, ArgHandler);
47
176
}
0 commit comments