History

arm64-win32 support: symbolic op-code constants

from: https://github.com/bold84/tinycc Author: Benjamin Oldenburg <benjamin.oldenburg@ordis.co.th> 2026-04-04 16:29:28 Committer: Benjamin Oldenburg <benjamin.oldenburg@ordis.co.th> 2026-04-04 16:29:28 Branch: win_arm64_clean Commit: 8b5ab1bb0141e66887bfbc4051688a3e478701a2 Also here: https://repo.or.cz/tinycc.git/shortlog/refs/mob/mob_bold84/win_arm64_clean This and the previous commits on mob is selected parts of that original branch. So it is not everything. It is not, for example: - unrelated whitespace changes in many files - a "pin msvcrt.dll" feature in tccpe.c (why that) - a native getenv() replacement in tcc.c (why that) - larger changes to the win32/lib runtime and tccrun.c (not needed) - a very gcc specific detail for struct alignent in tccgen.c - a custom set/longjmp implementation/replacement (not needed) - lots of rather basic test files in the win32 folder - a 'tests/asm' folder with some files (one file renamed to 140_test...c) - a .docs folder with one file

Benjamin Oldenburg committed 7 months ago

Commit 576cd2a1 parent 44e68532 files · +90 −84Browse files

Unified · Split

2 files
  1. arm64-gen.c +77 −72
  2. arm64-link.c +13 −12
arm64-gen.c+77−72
@@ -181,35 +181,35 @@ static uint32_t arm64_movi(int r, uint64_t x) · 180 unmodified lines
181 uint64_t m = 0xffff;181 uint64_t m = 0xffff;
182 int e;182 int e;
183 if (!(x & ~m))183 if (!(x & ~m))
184 return 0x52800000 | r | x << 5; // movz w(r),#(x)184 return ARM64_MOVZ | r | x << 5; // movz w(r),#(x)
185 if (!(x & ~(m << 16)))185 if (!(x & ~(m << 16)))
186 return 0x52a00000 | r | x >> 11; // movz w(r),#(x >> 16),lsl #16186 return (ARM64_MOVZ | ARM64_HW(1) | r | x >> 11); // movz w(r),#(x >> 16),lsl #16
187 if (!(x & ~(m << 32)))187 if (!(x & ~(m << 32)))
188 return 0xd2c00000 | r | x >> 27; // movz x(r),#(x >> 32),lsl #32188 return (ARM64_MOVZ64 | ARM64_HW(2) | r | x >> 27); // movz x(r),#(x >> 32),lsl #32
189 if (!(x & ~(m << 48)))189 if (!(x & ~(m << 48)))
190 return 0xd2e00000 | r | x >> 43; // movz x(r),#(x >> 48),lsl #48190 return (ARM64_MOVZ64 | ARM64_HW(3) | r | x >> 43); // movz x(r),#(x >> 48),lsl #48
191 if ((x & ~m) == m << 16)191 if ((x & ~m) == m << 16)
192 return (0x12800000 | r |192 return (ARM64_MOVN | r |
193 (~x << 5 & 0x1fffe0)); // movn w(r),#(~x)193 (~x << 5 & 0x1fffe0)); // movn w(r),#(~x)
194 if ((x & ~(m << 16)) == m)194 if ((x & ~(m << 16)) == m)
195 return (0x12a00000 | r |195 return (ARM64_MOVN | ARM64_HW(1) | r |
196 (~x >> 11 & 0x1fffe0)); // movn w(r),#(~x >> 16),lsl #16196 (~x >> 11 & 0x1fffe0)); // movn w(r),#(~x >> 16),lsl #16
197 if (!~(x | m))197 if (!~(x | m))
198 return (0x92800000 | r |198 return (ARM64_MOVN64 | r |
199 (~x << 5 & 0x1fffe0)); // movn x(r),#(~x)199 (~x << 5 & 0x1fffe0)); // movn x(r),#(~x)
200 if (!~(x | m << 16))200 if (!~(x | m << 16))
201 return (0x92a00000 | r |201 return (ARM64_MOVN64 | ARM64_HW(1) | r |
202 (~x >> 11 & 0x1fffe0)); // movn x(r),#(~x >> 16),lsl #16202 (~x >> 11 & 0x1fffe0)); // movn x(r),#(~x >> 16),lsl #16
203 if (!~(x | m << 32))203 if (!~(x | m << 32))
204 return (0x92c00000 | r |204 return (ARM64_MOVN64 | ARM64_HW(2) | r |
205 (~x >> 27 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32205 (~x >> 27 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32
206 if (!~(x | m << 48))206 if (!~(x | m << 48))
207 return (0x92e00000 | r |207 return (ARM64_MOVN64 | ARM64_HW(3) | r |
208 (~x >> 43 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32208 (~x >> 43 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32
209 if (!(x >> 32) && (e = arm64_encode_bimm64(x | x << 32)) >= 0)209 if (!(x >> 32) && (e = arm64_encode_bimm64(x | x << 32)) >= 0)
210 return 0x320003e0 | r | (uint32_t)e << 10; // movi w(r),#(x)210 return (ARM64_ORR_IMM | r | (uint32_t)e << 10); // movi w(r),#(x)
211 if ((e = arm64_encode_bimm64(x)) >= 0)211 if ((e = arm64_encode_bimm64(x)) >= 0)
212 return 0xb20003e0 | r | (uint32_t)e << 10; // movi x(r),#(x)212 return (ARM64_ORR_IMM | ARM64_SF(1) | r | (uint32_t)e << 10); // movi x(r),#(x)
213 return 0;213 return 0;
214}214}
215 215
@@ -221,7 +221,7 @@ static void arm64_movimm(int r, uint64_t x) · 5 unmodified lines
221 else {221 else {
222 // MOVZ/MOVN and 1-3 MOVKs222 // MOVZ/MOVN and 1-3 MOVKs
223 int z = 0, m = 0;223 int z = 0, m = 0;
224 uint32_t mov1 = 0xd2800000; // movz224 uint32_t mov1 = ARM64_MOVZ64; // movz
225 uint64_t x1 = x;225 uint64_t x1 = x;
226 for (i = 0; i < 64; i += 16) {226 for (i = 0; i < 64; i += 16) {
227 z += !(x >> i & 0xffff);227 z += !(x >> i & 0xffff);
@@ -229,7 +229,7 @@ static void arm64_movimm(int r, uint64_t x) · 1 unmodified line
229 }229 }
230 if (m > z) {230 if (m > z) {
231 x1 = ~x;231 x1 = ~x;
232 mov1 = 0x92800000; // movn232 mov1 = ARM64_MOVN64; // movn
233 }233 }
234 for (i = 0; i < 64; i += 16)234 for (i = 0; i < 64; i += 16)
235 if (x1 >> i & 0xffff) {235 if (x1 >> i & 0xffff) {
@@ -239,7 +239,7 @@ static void arm64_movimm(int r, uint64_t x) · 3 unmodified lines
239 }239 }
240 for (i += 16; i < 64; i += 16)240 for (i += 16; i < 64; i += 16)
241 if (x1 >> i & 0xffff)241 if (x1 >> i & 0xffff)
242 o(0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17);242 o(ARM64_MOVK | ARM64_SF(1) | r | (x >> i & 0xffff) << 5 | i << 17);
243 // movk x(r),#(*),lsl #(i)243 // movk x(r),#(*),lsl #(i)
244 }244 }
245}245}
@@ -254,8 +254,8 @@ ST_FUNC void gsym_addr(int t_, int a_) · 8 unmodified lines
254 uint32_t next = read32le(ptr);254 uint32_t next = read32le(ptr);
255 if (a - t + 0x8000000 >= 0x10000000)255 if (a - t + 0x8000000 >= 0x10000000)
256 tcc_error("branch out of range");256 tcc_error("branch out of range");
257 write32le(ptr, (a - t == 4 ? 0xd503201f : // nop257 write32le(ptr, (a - t == 4 ? ARM64_NOP :
258 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b258 ARM64_B | ((a - t) >> 2 & 0x3ffffff)));
259 t = next;259 t = next;
260 }260 }
261}261}
@@ -290,11 +290,10 @@ static void arm64_spoff(int reg, uint64_t off) · 28 unmodified lines
290 if (sub)290 if (sub)
291 off = -off;291 off = -off;
292 if (off < 4096)292 if (off < 4096)
293 o(0x910003e0 | sub << 30 | reg | off << 10);293 o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(31) | ARM64_RD(reg) | ARM64_IMM12(off));
294 // (add|sub) x(reg),sp,#(off)
295 else {294 else {
296 arm64_movimm(30, off); // use x30 for offset295 arm64_movimm(30, off);
297 o(0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30296 o(ARM64_ADD_REG | ARM64_SF(1) | ARM64_RM(30) | ARM64_RN(31) | ARM64_RD(reg) | (sub << 30));
298 }297 }
299}298}
300 299
@@ -323,14 +322,14 @@ static void arm64_ldrx(int sg, int sz_, int dst, int bas, uint64_t off) · 22 unmodified lines
323 if (sz >= 2)322 if (sz >= 2)
324 sg = 0;323 sg = 0;
325 if (!(off & ~scaled_mask))324 if (!(off & ~scaled_mask))
326 o(0x39400000 | dst | bas << 5 | off << (10 - sz) |325 o(ARM64_LDR_B | dst | bas << 5 | off << (10 - sz) |
327 (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)]326 (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)]
328 else if (off < 256 || -off <= 256)327 else if (off < 256 || -off <= 256)
329 o(0x38400000 | dst | bas << 5 | (off & 511) << 12 |328 o(ARM64_LDUR_B | dst | bas << 5 | (off & 511) << 12 |
330 (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)]329 (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)]
331 else {330 else {
332 arm64_movimm(30, off); // use x30 for offset331 arm64_movimm(30, off); // use x30 for offset
333 o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 |332 o(ARM64_LDR_B_REG | dst | bas << 5 | (uint32_t)30 << 16 |
334 (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30]333 (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30]
335 }334 }
336}335}
@@ -341,14 +340,14 @@ static void arm64_ldrv(int sz_, int dst, int bas, uint64_t off) · 4 unmodified lines
341 uint64_t scaled_mask = 0xffful << sz;340 uint64_t scaled_mask = 0xffful << sz;
342 341
343 if (!(off & ~scaled_mask))342 if (!(off & ~scaled_mask))
344 o(0x3d400000 | dst | bas << 5 | off << (10 - sz) |343 o(ARM64_LDR_SCALAR | dst | bas << 5 | off << (10 - sz) |
345 (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)]344 (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)]
346 else if (off < 256 || -off <= 256)345 else if (off < 256 || -off <= 256)
347 o(0x3c400000 | dst | bas << 5 | (off & 511) << 12 |346 o(ARM64_LDUR_Q_SIMD | dst | bas << 5 | (off & 511) << 12 |
348 (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)]347 (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)]
349 else {348 else {
350 arm64_movimm(30, off); // use x30 for offset349 arm64_movimm(30, off); // use x30 for offset
351 o(0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 |350 o(ARM64_LDR_Q_REG | dst | bas << 5 | (uint32_t)30 << 16 |
352 sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30]351 sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30]
353 }352 }
354}353}
@@ -480,25 +479,27 @@ static void arm64_sym(int r, Sym *sym, unsigned long addend) · 125 unmodified lines
480 o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | r); // add xr, xr, #sym479 o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | r); // add xr, xr, #sym
481#else480#else
482 greloca(cur_text_section, sym, ind, R_AARCH64_ADR_GOT_PAGE, 0);481 greloca(cur_text_section, sym, ind, R_AARCH64_ADR_GOT_PAGE, 0);
483 o(0x90000000 | r); // adrp xr, #sym482 o(ARM64_ADRP | r); // adrp xr, #sym
484 greloca(cur_text_section, sym, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);483 greloca(cur_text_section, sym, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
485 o(0xf9400000 | r | (r << 5)); // ld xr,[xr, #sym]484 o(ARM64_LDR_X | ARM64_RN(r) | r); // ld xr,[xr, #sym]
486#endif485#endif
487 if (addend) {486 if (addend) {
488 // add xr, xr, #addend487 // add xr, xr, #addend
489 if (addend & 0xffful)488 if (addend & 0xffful)
490 o(0x91000000 | r | r << 5 | (addend & 0xfff) << 10);489 o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | r |
490 (addend & 0xfff) << 10);
491 if (addend > 0xffful) {491 if (addend > 0xffful) {
492 // add xr, xr, #addend, lsl #12492 // add xr, xr, #addend, lsl #12
493 if (addend & 0xfff000ul)493 if (addend & 0xfff000ul)
494 o(0x91400000 | r | r << 5 | ((addend >> 12) & 0xfff) << 10);494 o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) |
495 ARM64_RN(r) | r | ((addend >> 12) & 0xfff) << 10);
495 if (addend > 0xfffffful) {496 if (addend > 0xfffffful) {
496 /* very unlikely */497 /* very unlikely */
497 int t = r ? 0 : 1;498 int t = r ? 0 : 1;
498 o(0xf81f0fe0 | t); /* str xt, [sp, #-16]! */499 o(ARM64_STR_X_PRE | 0x001F0FE0U | t); /* str xt, [sp, #-16]! */
499 arm64_movimm(t, addend & ~0xfffffful); // use xt for addent500 arm64_movimm(t, addend & ~0xfffffful); // use xt for addent
500 o(0x8B000000 | (t << 16) | (r << 5) | r); /* add xr, xr, xt */501 o(ARM64_ADD_REG | ARM64_SF(1) | ARM64_RM(t) | ARM64_RN(r) | r); /* add xr, xr, xt */
501 o(0xf84107e0 | t); /* ldr xt, [sp], #16 */502 o(ARM64_LDR_X_POST | 0x000107E0U | t); /* ldr xt, [sp], #16 */
502 }503 }
503 }504 }
504 }505 }
@@ -512,7 +513,7 @@ ST_FUNC void load(int r, SValue *sv) · 7 unmodified lines
512 int svr = sv->r & ~(VT_BOUNDED | VT_NONCONST);513 int svr = sv->r & ~(VT_BOUNDED | VT_NONCONST);
513 int svrv = svr & VT_VALMASK;514 int svrv = svr & VT_VALMASK;
514 uint64_t svcul = sv->c.i;515 uint64_t svcul = sv->c.i;
515 uint64_t svcoff = (int32_t)sv->c.i;516 uint64_t svcoff = (uint64_t)(int64_t)(int32_t)sv->c.i;
516 517
517 if (svr == (VT_LOCAL | VT_LVAL)) {518 if (svr == (VT_LOCAL | VT_LVAL)) {
518 if (IS_FREG(r))519 if (IS_FREG(r))
@@ -553,13 +554,13 @@ ST_FUNC void load(int r, SValue *sv) · 34 unmodified lines
553 554
554 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {555 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
555 arm64_sym(30, sv->sym, // use x30 for address556 arm64_sym(30, sv->sym, // use x30 for address
556 arm64_check_offset(0, arm64_type_size(svtt), svcul));557 arm64_check_offset(0, arm64_type_size(svtt), svcoff));
557 if (IS_FREG(r))558 if (IS_FREG(r))
558 arm64_ldrv(arm64_type_size(svtt), fltr(r), 30,559 arm64_ldrv(arm64_type_size(svtt), fltr(r), 30,
559 arm64_check_offset(1, arm64_type_size(svtt), svcul));560 arm64_check_offset(1, arm64_type_size(svtt), svcoff));
560 else561 else
561 arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(r), 30,562 arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(r), 30,
562 arm64_check_offset(1, arm64_type_size(svtt), svcul));563 arm64_check_offset(1, arm64_type_size(svtt), svcoff));
563 return;564 return;
564 }565 }
565 566
@@ -578,12 +579,12 @@ ST_FUNC void load(int r, SValue *sv) · 12 unmodified lines
578 if (svr < VT_CONST) {579 if (svr < VT_CONST) {
579 if (IS_FREG(r) && IS_FREG(svr))580 if (IS_FREG(r) && IS_FREG(svr))
580 if (svtt == VT_LDOUBLE)581 if (svtt == VT_LDOUBLE)
581 o(0x4ea01c00 | fltr(r) | fltr(svr) << 5);582 o(ARM64_MOV_V16B | fltr(r) | fltr(svr) << 5);
582 // mov v(r).16b,v(svr).16b583 // mov v(r).16b,v(svr).16b
583 else584 else
584 o(0x1e604000 | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr)585 o(ARM64_FMOV_SCALAR | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr)
585 else if (!IS_FREG(r) && !IS_FREG(svr))586 else if (!IS_FREG(r) && !IS_FREG(svr))
586 o(0xaa0003e0 | intr(r) | intr(svr) << 16); // mov x(r),x(svr)587 o(ARM64_MOV_REG | ARM64_SF(1) | intr(r) | intr(svr) << 16); // mov x(r),x(svr)
587 else588 else
588 assert(0);589 assert(0);
589 return;590 return;
@@ -602,7 +603,7 @@ ST_FUNC void load(int r, SValue *sv) · 12 unmodified lines
602 if (svr == VT_JMP || svr == VT_JMPI) {603 if (svr == VT_JMP || svr == VT_JMPI) {
603 int t = (svr == VT_JMPI);604 int t = (svr == VT_JMPI);
604 arm64_movimm(intr(r), t);605 arm64_movimm(intr(r), t);
605 o(0x14000002); // b .+8606 o(ARM64_B | 2); // b .+8
606 gsym(svcul);607 gsym(svcul);
607 arm64_movimm(intr(r), t ^ 1);608 arm64_movimm(intr(r), t ^ 1);
608 return;609 return;
@@ -623,7 +624,7 @@ ST_FUNC void load(int r, SValue *sv) · 14 unmodified lines
623 return;624 return;
624 }625 }
625 626
626 printf("load(%x, (%x, %x, %llx))\n", r, svtt, sv->r, (long long)svcul);627 printf("load(%x, (%x, %x, %lx))\n", r, svtt, sv->r, (long)svcul);
627 assert(0);628 assert(0);
628}629}
629 630
@@ -632,7 +633,7 @@ ST_FUNC void store(int r, SValue *sv) · 2 unmodified lines
632 int svtt = sv->type.t;633 int svtt = sv->type.t;
633 int svr = sv->r & ~VT_BOUNDED;634 int svr = sv->r & ~VT_BOUNDED;
634 int svrv = svr & VT_VALMASK;635 int svrv = svr & VT_VALMASK;
635 uint64_t svcoff = (int32_t)sv->c.i;636 uint64_t svcoff = (uint64_t)(int64_t)(int32_t)sv->c.i;
636 637
637 if (svr == (VT_LOCAL | VT_LVAL)) {638 if (svr == (VT_LOCAL | VT_LVAL)) {
638 if (IS_FREG(r))639 if (IS_FREG(r))
@@ -679,7 +680,7 @@ ST_FUNC void store(int r, SValue *sv) · 40 unmodified lines
679 return;680 return;
680 }681 }
681 682
682 printf("store(%x, (%x, %x, %llx))\n", r, svtt, sv->r, (long long)svcoff);683 printf("store(%x, (%x, %x, %lx))\n", r, svtt, sv->r, (long)svcoff);
683 assert(0);684 assert(0);
684}685}
685 686
@@ -688,13 +689,13 @@ static void arm64_gen_bl_or_b(int b) · 2 unmodified lines
688 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {689 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
689 greloca(cur_text_section, vtop->sym, ind,690 greloca(cur_text_section, vtop->sym, ind,
690 b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);691 b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);
691 o(0x14000000 | (uint32_t)!b << 31); // b/bl .692 o(b ? ARM64_B : ARM64_BL); // b/bl .
692 }693 }
693 else {694 else {
694#ifdef CONFIG_TCC_BCHECK695#ifdef CONFIG_TCC_BCHECK
695 vtop->r &= ~VT_MUSTBOUND;696 vtop->r &= ~VT_MUSTBOUND;
696#endif697#endif
697 o(0xd61f0000 | (uint32_t)!b << 21 | intr(gv(RC_R30)) << 5); // br/blr698 o((b ? ARM64_BR : ARM64_BLR) | intr(gv(RC_R30)) << 5); // br/blr
698 }699 }
699}700}
700 701
@@ -705,7 +706,7 @@ static void gen_bounds_call(int v) · 4 unmodified lines
705 Sym *sym = external_helper_sym(v);706 Sym *sym = external_helper_sym(v);
706 707
707 greloca(cur_text_section, sym, ind, R_AARCH64_CALL26, 0);708 greloca(cur_text_section, sym, ind, R_AARCH64_CALL26, 0);
708 o(0x94000000); // bl709 o(ARM64_BL); // bl
709}710}
710 711
711static void gen_bounds_prolog(void)712static void gen_bounds_prolog(void)
@@ -714,10 +715,10 @@ static void gen_bounds_prolog(void) · 2 unmodified lines
714 func_bound_offset = lbounds_section->data_offset;715 func_bound_offset = lbounds_section->data_offset;
715 func_bound_ind = ind;716 func_bound_ind = ind;
716 func_bound_add_epilog = 0;717 func_bound_add_epilog = 0;
717 o(0xd503201f); /* nop -> mov x0, lbound section pointer */718 o(ARM64_NOP); /* nop -> mov x0, lbound section pointer */
718 o(0xd503201f);719 o(ARM64_NOP);
719 o(0xd503201f);720 o(ARM64_NOP);
720 o(0xd503201f); /* nop -> call __bound_local_new */721 o(ARM64_NOP); /* nop -> call __bound_local_new */
721}722}
722 723
723static void gen_bounds_epilog(void)724static void gen_bounds_epilog(void)
@@ -1222,8 +1223,8 @@ ST_FUNC void gfunc_call(int nb_args) · 498 unmodified lines
1222 for (j = 0; j < n; j++)1223 for (j = 0; j < n; j++)
1223 o(0x3d000100 |1224 o(0x3d000100 |
1224 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |1225 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
1225 (a[i] / 2 - 8 + j) |1226 (fltr(REG_FRET) + j) |
1226 j << 10); // str ([sdq])(*),[x8,#(j * sz)]1227 j << 10); // str ([sdq])(j),[x8,#(j * sz)]
1227 }1228 }
1228 }1229 }
1229 }1230 }
@@ -1432,7 +1433,7 @@ ST_FUNC void gen_va_arg(CType *t) · 202 unmodified lines
1432 uint32_t r0, r1;1433 uint32_t r0, r1;
1433 1434
1434#ifdef TCC_TARGET_PE1435#ifdef TCC_TARGET_PE
1435 int indirect = 0, slot = (size + 7) & -8;1436 int indirect = 0, slot = size + 7 & -8;
1436 1437
1437 if (size > 16)1438 if (size > 16)
1438 indirect = 1, slot = 8;1439 indirect = 1, slot = 8;
@@ -1443,7 +1444,7 @@ ST_FUNC void gen_va_arg(CType *t) · 4 unmodified lines
1443 vtop[0].r = r1 | VT_LVAL;1444 vtop[0].r = r1 | VT_LVAL;
1444 r1 = intr(r1);1445 r1 = intr(r1);
1445 1446
1446 o(0xF9400000 | r0 << 5 | r1); // ldr x(r1),[x(r0)] // ap1447 o(ARM64_LDR_X | ARM64_RN(r0) | r1); // ldr x(r1),[x(r0)] // ap
1447 if (slot) {1448 if (slot) {
1448 if (slot == 16) {1449 if (slot == 16) {
1449 o(0x910363be); // add x30,x29,#2161450 o(0x910363be); // add x30,x29,#216
@@ -1460,7 +1461,7 @@ ST_FUNC void gen_va_arg(CType *t) · 10 unmodified lines
1460 }1461 }
1461 1462
1462 if (indirect)1463 if (indirect)
1463 o(0xF9400000 | ARM64_RN(r1) | r1); // ldr x(r1),[x(r1)]1464 o(ARM64_LDR_X | ARM64_RN(r1) | r1); // ldr x(r1),[x(r1)]
1464 1465
1465#else /* !PE */1466#else /* !PE */
1466 unsigned fsize = size, hfa = 1;1467 unsigned fsize = size, hfa = 1;
@@ -1476,6 +1477,7 @@ ST_FUNC void gen_va_arg(CType *t) · 9 unmodified lines
1476 1477
1477 if (!hfa) {1478 if (!hfa) {
1478 uint32_t n = size > 16 ? 8 : (size + 7) & -8;1479 uint32_t n = size > 16 ? 8 : (size + 7) & -8;
1480
1479#if !defined(TCC_TARGET_MACHO)1481#if !defined(TCC_TARGET_MACHO)
1480 o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs1482 o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs
1481 if (align == 16) {1483 if (align == 16) {
@@ -1486,21 +1488,24 @@ ST_FUNC void gen_va_arg(CType *t) · 4 unmodified lines
1486 o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)1488 o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)
1487 o(0x540000ad); // b.le .+201489 o(0x540000ad); // b.le .+20
1488#endif1490#endif
1489 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack1491
1492 o(ARM64_LDR_X | ARM64_RN(r0) | r1); // ldr x(r1),[x(r0)] // __stack
1490 if (align == 16) {1493 if (align == 16) {
1491 o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#151494 o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15
1492 o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-161495 o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16
1493 }1496 }
1494 o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)1497 o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)
1495 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack1498 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1499
1496#if !defined(TCC_TARGET_MACHO)1500#if !defined(TCC_TARGET_MACHO)
1497 o(0x14000004); // b .+161501 o(ARM64_B | 4); // b .+16
1498 o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs1502 o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs
1499 o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top1503 o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top
1500 o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw1504 o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
1501#endif1505#endif
1506
1502 if (size > 16)1507 if (size > 16)
1503 o(0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)]1508 o(ARM64_LDR_X | ARM64_RN(r1) | r1); // ldr x(r1),[x(r1)]
1504 }1509 }
1505 else {1510 else {
1506 uint32_t ssz = (size + 7) & -(uint32_t)8;1511 uint32_t ssz = (size + 7) & -(uint32_t)8;
@@ -1511,7 +1516,7 @@ ST_FUNC void gen_va_arg(CType *t) · 4 unmodified lines
1511 o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)1516 o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)
1512 b1 = ind; o(0x5400000d); // b.le lab11517 b1 = ind; o(0x5400000d); // b.le lab1
1513#endif1518#endif
1514 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack1519 o(ARM64_LDR_X | ARM64_RN(r0) | r1); // ldr x(r1),[x(r0)] // __stack
1515 if (fsize == 16) {1520 if (fsize == 16) {
1516 o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#151521 o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15
1517 o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-161522 o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16
@@ -1519,7 +1524,7 @@ ST_FUNC void gen_va_arg(CType *t) · 1 unmodified line
1519 o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)1524 o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)
1520 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack1525 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1521#if !defined(TCC_TARGET_MACHO)1526#if !defined(TCC_TARGET_MACHO)
1522 b2 = ind; o(0x14000000); // b lab21527 b2 = ind; o(ARM64_B); // b lab2
1523 // lab1:1528 // lab1:
1524 write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3);1529 write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3);
1525 o(0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs1530 o(0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs
@@ -1541,7 +1546,7 @@ ST_FUNC void gen_va_arg(CType *t) · 15 unmodified lines
1541 (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]1546 (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]
1542 }1547 }
1543 // lab2:1548 // lab2:
1544 write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2);1549 write32le(cur_text_section->data + b2, ARM64_B | ((ind - b2) >> 2));
1545#endif1550#endif
1546 }1551 }
1547#endif /* not pe */1552#endif /* not pe */
@@ -1590,7 +1595,7 @@ ST_FUNC void gfunc_return(CType *func_type) · 42 unmodified lines
1590 for (j = 0; j < n; j++)1595 for (j = 0; j < n; j++)
1591 o(0x3d400000 |1596 o(0x3d400000 |
1592 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |1597 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
1593 j | j << 10); // ldr ([sdq])(*),[x0,#(j * sz)]1598 (fltr(REG_FRET) + j) | j << 10); // ldr ([sdq])(j),[x0,#(j * sz)]
1594 }1599 }
1595 else1600 else
1596 gv(RC_FRET);1601 gv(RC_FRET);
@@ -1635,7 +1640,7 @@ ST_FUNC void gen_fill_nops(int bytes) · 38 unmodified lines
1635 if ((bytes & 3))1640 if ((bytes & 3))
1636 tcc_error("alignment of code section not multiple of 4");1641 tcc_error("alignment of code section not multiple of 4");
1637 while (bytes > 0) {1642 while (bytes > 0) {
1638 o(0xd503201f); // nop1643 o(ARM64_NOP); // nop
1639 bytes -= 4;1644 bytes -= 4;
1640 }1645 }
1641}1646}
@@ -1654,7 +1659,7 @@ ST_FUNC int gjmp(int t) · 12 unmodified lines
1654ST_FUNC void gjmp_addr(int a)1659ST_FUNC void gjmp_addr(int a)
1655{1660{
1656 assert(a - ind + 0x8000000 < 0x10000000);1661 assert(a - ind + 0x8000000 < 0x10000000);
1657 o(0x14000000 | ((a - ind) >> 2 & 0x3ffffff));1662 o(ARM64_B | (((a - ind) >> 2) & 0x3ffffff));
1658}1663}
1659 1664
1660ST_FUNC int gjmp_append(int n, int t)1665ST_FUNC int gjmp_append(int n, int t)
@@ -1759,7 +1764,7 @@ static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, · 98 unmodified lines
1759 val = l ? val : (uint32_t)val;1764 val = l ? val : (uint32_t)val;
1760 if (!(val & ~0xffful))1765 if (!(val & ~0xffful))
1761 o(0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10);1766 o(0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10);
1762 else if (!(val & ~(uint64_t)0xfff000))1767 else if (!(val & ~0xfff000ul))
1763 o(0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10);1768 o(0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10);
1764 else {1769 else {
1765 arm64_movimm(30, val); // use x301770 arm64_movimm(30, val); // use x30
@@ -2199,7 +2204,7 @@ ST_FUNC void gen_increment_tcov (SValue *sv) · 433 unmodified lines
2199 vtop->r = r1 = get_reg(RC_INT);2204 vtop->r = r1 = get_reg(RC_INT);
2200 r2 = get_reg(RC_INT);2205 r2 = get_reg(RC_INT);
2201 arm64_sym(r1, sv->sym, 0);2206 arm64_sym(r1, sv->sym, 0);
2202 o(0xf9400000 | (intr(r1)<<5) | intr(r2)); // ldr r2, [r1]2207 o(ARM64_LDR_X | ARM64_RN(intr(r1)) | intr(r2)); // ldr r2, [r1]
2203 o(0x91000400 | (intr(r2)<<5) | intr(r2)); // add r2, r2, #12208 o(0x91000400 | (intr(r2)<<5) | intr(r2)); // add r2, r2, #1
2204 o(0xf9000000 | (intr(r1)<<5) | intr(r2)); // str r2, [r1]2209 o(0xf9000000 | (intr(r1)<<5) | intr(r2)); // str r2, [r1]
2205 vpop();2210 vpop();
@@ -2236,21 +2241,21 @@ ST_FUNC void gen_clear_cache(void) · 30 unmodified lines
2236 o(0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz)2241 o(0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz)
2237 o(0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#12242 o(0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1
2238 o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)2243 o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
2239 b1 = ind; o(0x14000000); // b2244 b1 = ind; o(ARM64_B); // b
2240 lab1 = ind;2245 lab1 = ind;
2241 o(0xd50b7b20 | p); // dc cvau,x(p)2246 o(0xd50b7b20 | p); // dc cvau,x(p)
2242 o(0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz)2247 o(0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz)
2243 write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);2248 write32le(cur_text_section->data + b1, ARM64_B | ((ind - b1) >> 2));
2244 o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)2249 o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
2245 o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab12250 o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1
2246 o(0xd5033b9f); // dsb ish2251 o(0xd5033b9f); // dsb ish
2247 o(0x51000400 | p | isz << 5); // sub w(p),w(isz),#12252 o(0x51000400 | p | isz << 5); // sub w(p),w(isz),#1
2248 o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)2253 o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
2249 b1 = ind; o(0x14000000); // b2254 b1 = ind; o(ARM64_B); // b
2250 lab1 = ind;2255 lab1 = ind;
2251 o(0xd50b7520 | p); // ic ivau,x(p)2256 o(0xd50b7520 | p); // ic ivau,x(p)
2252 o(0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz)2257 o(0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz)
2253 write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);2258 write32le(cur_text_section->data + b1, ARM64_B | ((ind - b1) >> 2));
2254 o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)2259 o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
2255 o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab12260 o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1
2256 o(0xd5033b9f); // dsb ish2261 o(0xd5033b9f); // dsb ish
arm64-link.c+13−12
@@ -131,17 +131,18 @@ ST_FUNC void relocate_plt(TCCState *s1) · 130 unmodified lines
131 uint64_t off = (got >> 12) - (plt >> 12);131 uint64_t off = (got >> 12) - (plt >> 12);
132 if ((off + ((uint32_t)1 << 20)) >> 21)132 if ((off + ((uint32_t)1 << 20)) >> 21)
133 tcc_error_noabort("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);133 tcc_error_noabort("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
134 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!134 write32le(p, ARM64_STP_X_PRE | ARM64_RT(16) | ARM64_RT2(30) |
135 write32le(p + 4, (0x90000010 | // adrp x16,...135 ARM64_RN(31) | ARM64_IMM7(-2)); // stp x16,x30,[sp,#-16]!
136 write32le(p + 4, (ARM64_ADRP | ARM64_RD(16) | // adrp x16,...
136 (off & 0x1ffffc) << 3 | (off & 3) << 29));137 (off & 0x1ffffc) << 3 | (off & 3) << 29));
137 write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]138 write32le(p + 8, (ARM64_LDR_X | ARM64_RT(17) | ARM64_RN(16) | // ldr x17,[x16,#...]
138 (got & 0xff8) << 7));139 (got & 0xff8) << 7));
139 write32le(p + 12, (0x91000210 | // add x16,x16,#...140 write32le(p + 12, (ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RD(16) | ARM64_RN(16) | // add x16,x16,#...
140 (got & 0xfff) << 10));141 (got & 0xfff) << 10));
141 write32le(p + 16, 0xd61f0220); // br x17142 write32le(p + 16, ARM64_BR | ARM64_RN(17)); // br x17
142 write32le(p + 20, 0xd503201f); // nop143 write32le(p + 20, ARM64_NOP); // nop
143 write32le(p + 24, 0xd503201f); // nop144 write32le(p + 24, ARM64_NOP); // nop
144 write32le(p + 28, 0xd503201f); // nop145 write32le(p + 28, ARM64_NOP); // nop
145 p += 32;146 p += 32;
146 got = s1->got->sh_addr;147 got = s1->got->sh_addr;
147 while (p < p_end) {148 while (p < p_end) {
@@ -150,13 +151,13 @@ ST_FUNC void relocate_plt(TCCState *s1) · 2 unmodified lines
150 uint64_t off = (addr >> 12) - (pc >> 12);151 uint64_t off = (addr >> 12) - (pc >> 12);
151 if ((off + ((uint32_t)1 << 20)) >> 21)152 if ((off + ((uint32_t)1 << 20)) >> 21)
152 tcc_error_noabort("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);153 tcc_error_noabort("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
153 write32le(p, (0x90000010 | // adrp x16,...154 write32le(p, (ARM64_ADRP | ARM64_RD(16) | // adrp x16,...
154 (off & 0x1ffffc) << 3 | (off & 3) << 29));155 (off & 0x1ffffc) << 3 | (off & 3) << 29));
155 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]156 write32le(p + 4, (ARM64_LDR_X | ARM64_RT(17) | ARM64_RN(16) | // ldr x17,[x16,#...]
156 (addr & 0xff8) << 7));157 (addr & 0xff8) << 7));
157 write32le(p + 8, (0x91000210 | // add x16,x16,#...158 write32le(p + 8, (ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RD(16) | ARM64_RN(16) | // add x16,x16,#...
158 (addr & 0xfff) << 10));159 (addr & 0xfff) << 10));
159 write32le(p + 12, 0xd61f0220); // br x17160 write32le(p + 12, ARM64_BR | ARM64_RN(17)); // br x17
160 p += 16;161 p += 16;
161 }162 }
162 }163 }

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