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 (INRANGE(i
.op
, Oalloc
, Oalloc1
)) {
168 salloc(i
.to
, i
.arg
[0], fn
);
169 fixarg(&i0
->arg
[0], Kl
, 0, fn
);
172 if (iscmp(i
.op
, &ck
, &cc
)) {
173 emit(Oflag
, i
.cls
, i
.to
, R
, R
);
175 if (selcmp(i
.arg
, ck
, fn
))
183 iarg
= curi
->arg
; /* fixarg() can change curi */
184 fixarg(&iarg
[0], argcls(&i
, 0), 0, fn
);
185 fixarg(&iarg
[1], argcls(&i
, 1), 0, fn
);
190 seljmp(Blk
*b
, Fn
*fn
)
196 switch (b
->jmp
.type
) {
198 assert(0 && "TODO 2");
210 i
= &b
->ins
[b
->nins
];
212 if (req((--i
)->to
, r
)) {
213 use
= fn
->tmp
[r
.val
].nuse
;
218 && iscmp(ir
->op
, &ck
, &cc
)) {
219 if (selcmp(ir
->arg
, ck
, fn
))
221 b
->jmp
.type
= Jjf
+ cc
;
222 *ir
= (Ins
){.op
= Onop
};
225 selcmp((Ref
[]){r
, CON_Z
}, Kw
, fn
);
226 b
->jmp
.type
= Jjfine
;
239 /* assign slots to fast allocs */
241 /* specific to NAlign == 3 */ /* or change n=4 and sz /= 4 below */
242 for (al
=Oalloc
, n
=4; al
<=Oalloc1
; al
++, n
*=2)
243 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++)
245 if (rtype(i
->arg
[0]) != RCon
)
247 sz
= fn
->con
[i
->arg
[0].val
].bits
.i
;
248 if (sz
< 0 || sz
>= INT_MAX
-15)
249 err("invalid alloc size %"PRId64
, sz
);
250 sz
= (sz
+ n
-1) & -n
;
252 fn
->tmp
[i
->to
.val
].slot
= fn
->slot
;
254 *i
= (Ins
){.op
= Onop
};
257 for (b
=fn
->start
; b
; b
=b
->link
) {
259 for (sb
=(Blk
*[3]){b
->s1
, b
->s2
, 0}; *sb
; sb
++)
260 for (p
=(*sb
)->phi
; p
; p
=p
->link
) {
261 for (n
=0; p
->blk
[n
] != b
; n
++)
262 assert(n
+1 < p
->narg
);
263 fixarg(&p
->arg
[n
], p
->cls
, 1, fn
);
266 for (i
=&b
->ins
[b
->nins
]; i
!=b
->ins
;)
268 b
->nins
= &insb
[NIns
] - curi
;
269 idup(&b
->ins
, curi
, b
->nins
);
273 fprintf(stderr
, "\n> After instruction selection:\n");