History

arm64-gen.c: Avoid some cases of undefined behaviour.

Also make some functions more portable.

Edmund Grimley Evans committed 11 years ago

Commit a7334f71 parent c52128c1 file · +55 −44Browse files

Unified · Split

arm64-gen.c+55−44
@@ -286,26 +286,28 @@ static void arm64_spoff(int reg, uint64_t off) · 285 unmodified lines
286286 }
287287 }
288288
289−static void arm64_ldrx(int sg, int sz, int dst, int bas, uint64_t off)
289+static void arm64_ldrx(int sg, int sz_, int dst, int bas, uint64_t off)
290290 {
291+ uint32_t sz = sz_;
291292 if (sz >= 2)
292293 sg = 0;
293− if (!(off & ~(0xfff << sz)))
294+ if (!(off & ~((uint32_t)0xfff << sz)))
294295 o(0x39400000 | dst | bas << 5 | off << (10 - sz) |
295− !!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)]
296+ (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)]
296297 else if (off < 256 || -off <= 256)
297298 o(0x38400000 | dst | bas << 5 | (off & 511) << 12 |
298− !!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)]
299+ (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)]
299300 else {
300301 arm64_movimm(30, off); // use x30 for offset
301− o(0x38206800 | dst | bas << 5 | 30 << 16 |
302− (!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30]
302+ o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 |
303+ (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30]
303304 }
304305 }
305306
306−static void arm64_ldrv(int sz, int dst, int bas, uint64_t off)
307+static void arm64_ldrv(int sz_, int dst, int bas, uint64_t off)
307308 {
308− if (!(off & ~(0xfff << sz)))
309+ uint32_t sz = sz_;
310+ if (!(off & ~((uint32_t)0xfff << sz)))
309311 o(0x3d400000 | dst | bas << 5 | off << (10 - sz) |
310312 (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)]
311313 else if (off < 256 || -off <= 256)
@@ -313,13 +315,14 @@ static void arm64_ldrv(int sz, int dst, int bas, uint64_t off) · 1 unmodified line
313315 (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)]
314316 else {
315317 arm64_movimm(30, off); // use x30 for offset
316− o(0x3c606800 | dst | bas << 5 | 30 << 16 | sz << 30 | (sz & 4) << 21);
317− // ldr (s|d|q)(dst),[x(bas),x30]
318+ o(0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 |
319+ sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30]
318320 }
319321 }
320322
321−static void arm64_ldrs(int reg, int size)
323+static void arm64_ldrs(int reg_, int size)
322324 {
325+ uint32_t reg = reg_;
323326 // Use x30 for intermediate value in some cases.
324327 switch (size) {
325328 default: assert(0); break;
@@ -395,9 +398,10 @@ static void arm64_ldrs(int reg, int size) · 69 unmodified lines
395398 }
396399 }
397400
398−static void arm64_strx(int sz, int dst, int bas, uint64_t off)
401+static void arm64_strx(int sz_, int dst, int bas, uint64_t off)
399402 {
400− if (!(off & ~(0xfff << sz)))
403+ uint32_t sz = sz_;
404+ if (!(off & ~((uint32_t)0xfff << sz)))
401405 o(0x39000000 | dst | bas << 5 | off << (10 - sz) | sz << 30);
402406 // str(*) x(dst),[x(bas],#(off)]
403407 else if (off < 256 || -off <= 256)
@@ -405,14 +409,15 @@ static void arm64_strx(int sz, int dst, int bas, uint64_t off) · 1 unmodified line
405409 // stur(*) x(dst),[x(bas],#(off)]
406410 else {
407411 arm64_movimm(30, off); // use x30 for offset
408− o(0x38206800 | dst | bas << 5 | 30 << 16 | sz << 30);
412+ o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | sz << 30);
409413 // str(*) x(dst),[x(bas),x30]
410414 }
411415 }
412416
413−static void arm64_strv(int sz, int dst, int bas, uint64_t off)
417+static void arm64_strv(int sz_, int dst, int bas, uint64_t off)
414418 {
415− if (!(off & ~(0xfff << sz)))
419+ uint32_t sz = sz_;
420+ if (!(off & ~((uint32_t)0xfff << sz)))
416421 o(0x3d000000 | dst | bas << 5 | off << (10 - sz) |
417422 (sz & 4) << 21 | (sz & 3) << 30); // str (s|d|q)(dst),[x(bas),#(off)]
418423 else if (off < 256 || -off <= 256)
@@ -420,8 +425,8 @@ static void arm64_strv(int sz, int dst, int bas, uint64_t off) · 1 unmodified line
420425 (sz & 4) << 21 | (sz & 3) << 30); // stur (s|d|q)(dst),[x(bas),#(off)]
421426 else {
422427 arm64_movimm(30, off); // use x30 for offset
423− o(0x3c206800 | dst | bas << 5 | 30 << 16 | sz << 30 | (sz & 4) << 21);
424− // str (s|d|q)(dst),[x(bas),x30]
428+ o(0x3c206800 | dst | bas << 5 | (uint32_t)30 << 16 |
429+ sz << 30 | (sz & 4) << 21); // str (s|d|q)(dst),[x(bas),x30]
425430 }
426431 }
427432
@@ -458,7 +463,8 @@ ST_FUNC void load(int r, SValue *sv) · 30 unmodified lines
458463 int svtt = sv->type.t;
459464 int svr = sv->r & ~VT_LVAL_TYPE;
460465 int svrv = svr & VT_VALMASK;
461− uint64_t svcul = (int32_t)sv->c.ul;
466+ uint64_t svcul = (uint32_t)sv->c.ul;
467+ svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul;
462468
463469 if (svr == (VT_LOCAL | VT_LVAL)) {
464470 if (IS_FREG(r))
@@ -519,7 +525,7 @@ ST_FUNC void load(int r, SValue *sv) · 54 unmodified lines
519525 o(0xd10003a0 | intr(r) | -svcul << 10); // sub x(r),x29,#...
520526 else {
521527 arm64_movimm(30, -svcul); // use x30 for offset
522− o(0xcb0003a0 | intr(r) | 30 << 16); // sub x(r),x29,x30
528+ o(0xcb0003a0 | intr(r) | (uint32_t)30 << 16); // sub x(r),x29,x30
523529 }
524530 return;
525531 }
@@ -552,7 +558,8 @@ ST_FUNC void store(int r, SValue *sv) · 26 unmodified lines
552558 int svtt = sv->type.t;
553559 int svr = sv->r & ~VT_LVAL_TYPE;
554560 int svrv = svr & VT_VALMASK;
555− uint64_t svcul = (int32_t)sv->c.ul;
561+ uint64_t svcul = (uint32_t)sv->c.ul;
562+ svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul;
556563
557564 if (svr == (VT_LOCAL | VT_LVAL)) {
558565 if (IS_FREG(r))
@@ -594,7 +601,7 @@ static void arm64_gen_bl_or_b(int b) · 35 unmodified lines
594601 o(0x94000000); // bl .
595602 }
596603 else
597− o(0xd61f0000 | !b << 21 | intr(gv(RC_R30)) << 5); // br/blr
604+ o(0xd61f0000 | (uint32_t)!b << 21 | intr(gv(RC_R30)) << 5); // br/blr
598605 }
599606
600607 static int arm64_hfa_aux(CType *type, int *fsize, int num)
@@ -930,7 +937,7 @@ ST_FUNC void gfunc_call(int nb_args) · 329 unmodified lines
930937 else if (a[i] < 32) {
931938 // value in floating-point registers
932939 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
933− int j, sz, n = arm64_hfa(&vtop->type, &sz);
940+ uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
934941 vtop->type.t = VT_PTR;
935942 gaddrof();
936943 gv(RC_R30);
@@ -968,7 +975,7 @@ ST_FUNC void gfunc_call(int nb_args) · 31 unmodified lines
968975 if (bt == VT_BYTE || bt == VT_SHORT)
969976 // Promote small integers:
970977 o(0x13001c00 | (bt == VT_SHORT) << 13 |
971− !!(rt & VT_UNSIGNED) << 30); // [su]xt[bh] w0,w0
978+ (uint32_t)!!(rt & VT_UNSIGNED) << 30); // [su]xt[bh] w0,w0
972979 else if (bt == VT_STRUCT && !(a[0] & 1)) {
973980 // A struct was returned in registers, so write it out:
974981 gv(RC_R(8));
@@ -983,7 +990,7 @@ ST_FUNC void gfunc_call(int nb_args) · 8 unmodified lines
983990
984991 }
985992 else if (a[0] == 16) {
986− int j, sz, n = arm64_hfa(return_type, &sz);
993+ uint32_t j, sz, n = arm64_hfa(return_type, &sz);
987994 for (j = 0; j < n; j++)
988995 o(0x3d000100 |
989996 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
@@ -1053,14 +1060,14 @@ ST_FUNC void gfunc_prolog(CType *func_type) · 63 unmodified lines
10531060 (!(a[i] & 1) && size > 8)) * 8;
10541061 }
10551062 else if (a[i] < 32) {
1056− int hfa = arm64_hfa(&sym->type, 0);
1063+ uint32_t hfa = arm64_hfa(&sym->type, 0);
10571064 arm64_func_va_list_vr_offs = (a[i] / 2 - 16 +
10581065 (hfa ? hfa : 1)) * 16;
10591066 }
10601067
10611068 // HFAs of float and double need to be written differently:
10621069 if (16 <= a[i] && a[i] < 32 && (sym->type.t & VT_BTYPE) == VT_STRUCT) {
1063− int j, sz, k = arm64_hfa(&sym->type, &sz);
1070+ uint32_t j, sz, k = arm64_hfa(&sym->type, &sz);
10641071 if (sz < 16)
10651072 for (j = 0; j < k; j++) {
10661073 o(0x3d0003e0 | -(sz & 8) << 27 | (sz & 4) << 29 |
@@ -1196,7 +1203,8 @@ ST_FUNC void gen_va_arg(CType *t) · 129 unmodified lines
11961203 }
11971204 }
11981205
1199−ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize)
1206+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret,
1207+ int *align, int *regsize)
12001208 {
12011209 return 0;
12021210 }
@@ -1231,7 +1239,7 @@ ST_FUNC void greturn(void) · 28 unmodified lines
12311239 }
12321240 case 16:
12331241 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
1234− int j, sz, n = arm64_hfa(&vtop->type, &sz);
1242+ uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
12351243 gaddrof();
12361244 gv(RC_R(0));
12371245 for (j = 0; j < n; j++)
@@ -1304,7 +1312,7 @@ ST_FUNC int gtst(int inv, int t) · 66 unmodified lines
13041312 {
13051313 int bt = vtop->type.t & VT_BTYPE;
13061314 if (bt == VT_LDOUBLE) {
1307− int a, b, f = fltr(gv(RC_FLOAT));
1315+ uint32_t a, b, f = fltr(gv(RC_FLOAT));
13081316 a = get_reg(RC_INT);
13091317 vpushi(0);
13101318 vtop[0].r = a;
@@ -1318,13 +1326,13 @@ ST_FUNC int gtst(int inv, int t) · 7 unmodified lines
13181326 --vtop;
13191327 }
13201328 else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
1321− int a = fltr(gv(RC_FLOAT));
1329+ uint32_t a = fltr(gv(RC_FLOAT));
13221330 o(0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp
13231331 o(0x54000040 | !!inv); // b.eq/b.ne .+8
13241332 }
13251333 else {
1326− int ll = (bt == VT_PTR || bt == VT_LLONG);
1327− int a = intr(gv(RC_INT));
1334+ uint32_t ll = (bt == VT_PTR || bt == VT_LLONG);
1335+ uint32_t a = intr(gv(RC_INT));
13281336 o(0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+8
13291337 }
13301338 --vtop;
@@ -1362,7 +1370,7 @@ static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, · 31 unmodified lines
13621370 switch (op) {
13631371
13641372 case '+': {
1365− int s = l ? val >> 63 : val >> 31;
1373+ uint32_t s = l ? val >> 63 : val >> 31;
13661374 val = s ? -val : val;
13671375 val = l ? val : (uint32_t)val;
13681376 if (!(val & ~(uint64_t)0xfff))
@@ -1470,7 +1478,8 @@ static void arm64_gen_opil(int op, uint32_t l) · 101 unmodified lines
14701478 case '%':
14711479 // Use x30 for quotient:
14721480 o(0x1ac00c00 | l << 31 | 30 | a << 5 | b << 16); // sdiv
1473− o(0x1b008000 | l << 31 | x | 30 << 5 | b << 16 | a << 10); // msub
1481+ o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
1482+ b << 16 | a << 10); // msub
14741483 break;
14751484 case '&':
14761485 o(0x0a000000 | l << 31 | x | a << 5 | b << 16); // and
@@ -1549,7 +1558,8 @@ static void arm64_gen_opil(int op, uint32_t l) · 72 unmodified lines
15491558 case TOK_UMOD:
15501559 // Use x30 for quotient:
15511560 o(0x1ac00800 | l << 31 | 30 | a << 5 | b << 16); // udiv
1552− o(0x1b008000 | l << 31 | x | 30 << 5 | b << 16 | a << 10); // msub
1561+ o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
1562+ b << 16 | a << 10); // msub
15531563 break;
15541564 default:
15551565 assert(0);
@@ -1568,7 +1578,7 @@ ST_FUNC void gen_opl(int op) · 12 unmodified lines
15681578
15691579 ST_FUNC void gen_opf(int op)
15701580 {
1571− int x, a, b, dbl;
1581+ uint32_t x, a, b, dbl;
15721582
15731583 if (vtop[0].type.t == VT_LDOUBLE) {
15741584 CType type = vtop[0].type;
@@ -1596,7 +1606,7 @@ ST_FUNC void gen_opf(int op) · 21 unmodified lines
15961606 vtop->type = type;
15971607 else {
15981608 o(0x7100001f); // cmp w0,#0
1599− o(0x1a9f07e0 | cond << 12); // cset w0,(cond)
1609+ o(0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)
16001610 }
16011611 return;
16021612 }
@@ -1668,7 +1678,7 @@ ST_FUNC void gen_opf(int op) · 65 unmodified lines
16681678 // Generate sign extension from 32 to 64 bits:
16691679 ST_FUNC void gen_cvt_sxtw(void)
16701680 {
1671− int r = intr(gv(RC_INT));
1681+ uint32_t r = intr(gv(RC_INT));
16721682 o(0x93407c00 | r | r << 5); // sxtw x(r),w(r)
16731683 }
16741684
@@ -1690,12 +1700,13 @@ ST_FUNC void gen_cvt_itof(int t) · 15 unmodified lines
16901700 else {
16911701 int d, n = intr(gv(RC_INT));
16921702 int s = !(vtop->type.t & VT_UNSIGNED);
1693− int l = ((vtop->type.t & VT_BTYPE) == VT_LLONG);
1703+ uint32_t l = ((vtop->type.t & VT_BTYPE) == VT_LLONG);
16941704 --vtop;
16951705 d = get_reg(RC_FLOAT);
16961706 ++vtop;
16971707 vtop[0].r = d;
1698− o(0x1e220000 | !s << 16 | (t != VT_FLOAT) << 22 | fltr(d) |
1708+ o(0x1e220000 | (uint32_t)!s << 16 |
1709+ (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) |
16991710 l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n)
17001711 }
17011712 }
@@ -1716,14 +1727,14 @@ ST_FUNC void gen_cvt_ftoi(int t) · 14 unmodified lines
17161727 }
17171728 else {
17181729 int d, n = fltr(gv(RC_FLOAT));
1719− int l = ((vtop->type.t & VT_BTYPE) != VT_FLOAT);
1730+ uint32_t l = ((vtop->type.t & VT_BTYPE) != VT_FLOAT);
17201731 --vtop;
17211732 d = get_reg(RC_INT);
17221733 ++vtop;
17231734 vtop[0].r = d;
17241735 o(0x1e380000 |
1725− !!(t & VT_UNSIGNED) << 16 |
1726− ((t & VT_BTYPE) == VT_LLONG) << 31 | intr(d) |
1736+ (uint32_t)!!(t & VT_UNSIGNED) << 16 |
1737+ (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(d) |
17271738 l << 22 | n << 5); // fcvtz[su] [wx](d),[sd](n)
17281739 }
17291740 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t