168
169
mk_arith_ri(S, Dst, Src2, commute_arithop(ArithOp), Src1).
170
171
mk_arith_ri(S, Dst, Src1, ArithOp, Src2) ->
171
{FixAm1,NewArithOp,Am1} = fix_aluop_imm(ArithOp, Src2),
172
FixAm1 ++ [hipe_arm:mk_alu(NewArithOp, S, Dst, Src1, Am1)].
173
'mul' -> % mul/smull only take reg/reg operands
174
Tmp = new_untagged_temp(),
176
mk_arith_rr(S, Dst, Src1, ArithOp, Tmp));
177
_ -> % add/sub/orr/and/eor have reg/am1 operands
178
{FixAm1,NewArithOp,Am1} = fix_aluop_imm(ArithOp, Src2),
179
FixAm1 ++ [hipe_arm:mk_alu(NewArithOp, S, Dst, Src1, Am1)]
174
182
mk_arith_rr(S, Dst, Src1, ArithOp, Src2) ->
175
[hipe_arm:mk_alu(ArithOp, S, Dst, Src1, Src2)].
185
%% To check for overflow in 32x32->32 multiplication:
186
%% smull Dst,TmpHi,Src1,Src2
187
%% mov TmpSign,Dst,ASR #31
189
%% [bne OverflowLabel]
190
TmpHi = new_untagged_temp(),
191
TmpSign = new_untagged_temp(),
192
[hipe_arm:mk_smull(Dst, TmpHi, Src1, Src2),
193
hipe_arm:mk_move(TmpSign, {Dst,'asr',31}),
194
hipe_arm:mk_cmp('cmp', TmpSign, TmpHi)];
196
[hipe_arm:mk_alu(ArithOp, S, Dst, Src1, Src2)]
177
199
fix_aluop_imm(AluOp, Imm) -> % {FixAm1,NewAluOp,Am1}
178
200
case hipe_arm:try_aluop_imm(AluOp, Imm) of
187
209
{Dst, Map0} = conv_dst(hipe_rtl:alub_dst(I), Map),
188
210
{Src1, Map1} = conv_src(hipe_rtl:alub_src1(I), Map0),
189
211
{Src2, Map2} = conv_src(hipe_rtl:alub_src2(I), Map1),
190
Cond = conv_alub_cond(hipe_rtl:alub_cond(I)),
212
RtlAluOp = hipe_rtl:alub_op(I),
213
Cond0 = conv_alub_cond(hipe_rtl:alub_cond(I)),
215
case {RtlAluOp,Cond0} of
216
{'mul','vs'} -> 'ne'; % overflow becomes not-equal
217
{'mul','vc'} -> 'eq'; % no-overflow becomes equal
218
{'mul',_} -> exit({?MODULE,I});
191
221
I2 = mk_pseudo_bc(
193
223
hipe_rtl:alub_true_label(I),
194
224
hipe_rtl:alub_false_label(I),
195
225
hipe_rtl:alub_pred(I)),
196
RtlAluOp = hipe_rtl:alub_op(I),
198
227
I1 = mk_alu(S, Dst, Src1, RtlAluOp, Src2),
199
228
{I1 ++ I2, Map2, Data}.
454
483
Index = new_untagged_temp(),
455
484
Am3 = hipe_arm:mk_am3(Base, Sign, Index),
456
[mk_li(Index, AbsOffset),
457
hipe_arm:mk_ldrsb(Dst, Am3)]
485
mk_li(Index, AbsOffset,
486
[hipe_arm:mk_ldrsb(Dst, Am3)])
460
489
mk_ldrsb_rr(Dst, Base1, Base2) ->