14 imm(Con
*c
, int k
, int64_t *pn
)
30 if ((n
& 0x000fff) == n
)
32 if ((n
& 0xfff000) == n
)
34 if ((n
& 0xffffff) == n
)
40 arm64_logimm(uint64_t x
, int k
)
45 x
= (x
& 0xffffffff) | x
<< 32;
50 if (x
== 0xaaaaaaaaaaaaaaaa)
53 if (0x1111111111111111 * n
== x
)
56 if (0x0101010101010101 * n
== x
)
59 if (0x0001000100010001 * n
== x
)
62 if (0x0000000100000001 * n
== x
)
66 return (n
& (n
+ (n
& -n
))) == 0;
70 fixarg(Ref
*pr
, int k
, int phi
, Fn
*fn
)
80 if (KBASE(k
) == 0 && phi
)
82 r1
= newtmp("isel", k
, fn
);
84 emit(Ocopy
, k
, r1
, r0
, R
);
87 n
= gasstash(&c
->bits
, KWIDE(k
) ? 8 : 4);
88 vgrow(&fn
->con
, ++fn
->ncon
);
89 c
= &fn
->con
[fn
->ncon
-1];
90 sprintf(buf
, "fp%d", n
);
91 *c
= (Con
){.type
= CAddr
, .local
= 1};
92 c
->label
= intern(buf
);
93 r2
= newtmp("isel", Kl
, fn
);
94 emit(Oload
, k
, r1
, r2
, R
);
95 emit(Ocopy
, Kl
, r2
, CON(c
-fn
->con
), R
);
100 s
= fn
->tmp
[r0
.val
].slot
;
103 r1
= newtmp("isel", Kl
, fn
);
104 emit(Oaddr
, Kl
, r1
, SLOT(s
), R
);
111 selcmp(Ref arg
[2], int k
, Fn
*fn
)
119 emit(Oafcmp
, k
, R
, arg
[0], arg
[1]);
121 fixarg(&iarg
[0], k
, 0, fn
);
122 fixarg(&iarg
[1], k
, 0, fn
);
125 swap
= rtype(arg
[0]) == RCon
;
134 if (rtype(r
) == RCon
) {
136 switch (imm(c
, k
, &n
)) {
151 emit(cmp
, k
, R
, arg
[0], r
);
153 fixarg(&iarg
[0], k
, 0, fn
);
155 fixarg(&iarg
[1], k
, 0, fn
);
166 if (iscmp(i
.op
, &ck
, &cc
)) {
167 emit(Oflag
, i
.cls
, i
.to
, R
, R
);
169 if (selcmp(i
.arg
, ck
, fn
))
173 } else if (i
.op
!= Onop
) {
175 iarg
= curi
->arg
; /* fixarg() can change curi */
176 fixarg(&iarg
[0], argcls(&i
, 0), 0, fn
);
177 fixarg(&iarg
[1], argcls(&i
, 1), 0, fn
);
182 seljmp(Blk
*b
, Fn
*fn
)
188 switch (b
->jmp
.type
) {
190 assert(0 && "TODO 2");
202 i
= &b
->ins
[b
->nins
];
204 if (req((--i
)->to
, r
)) {
205 use
= fn
->tmp
[r
.val
].nuse
;
210 && iscmp(ir
->op
, &ck
, &cc
)) {
211 if (selcmp(ir
->arg
, ck
, fn
))
213 b
->jmp
.type
= Jjf
+ cc
;
214 *ir
= (Ins
){.op
= Onop
};
217 selcmp((Ref
[]){r
, CON_Z
}, Kw
, fn
);
218 b
->jmp
.type
= Jjfine
;
231 /* assign slots to fast allocs */
233 /* specific to NAlign == 3 */ /* or change n=4 and sz /= 4 below */
234 for (al
=Oalloc
, n
=4; al
<=Oalloc1
; al
++, n
*=2)
235 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++)
237 if (rtype(i
->arg
[0]) != RCon
)
239 sz
= fn
->con
[i
->arg
[0].val
].bits
.i
;
240 if (sz
< 0 || sz
>= INT_MAX
-15)
241 err("invalid alloc size %"PRId64
, sz
);
242 sz
= (sz
+ n
-1) & -n
;
244 fn
->tmp
[i
->to
.val
].slot
= fn
->slot
;
246 *i
= (Ins
){.op
= Onop
};
249 for (b
=fn
->start
; b
; b
=b
->link
) {
251 for (sb
=(Blk
*[3]){b
->s1
, b
->s2
, 0}; *sb
; sb
++)
252 for (p
=(*sb
)->phi
; p
; p
=p
->link
) {
253 for (n
=0; p
->blk
[n
] != b
; n
++)
254 assert(n
+1 < p
->narg
);
255 fixarg(&p
->arg
[n
], p
->cls
, 1, fn
);
258 for (i
=&b
->ins
[b
->nins
]; i
!=b
->ins
;)
260 b
->nins
= &insb
[NIns
] - curi
;
261 idup(&b
->ins
, curi
, b
->nins
);
265 fprintf(stderr
, "\n> After instruction selection:\n");