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
Unified · Split
| @@ -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 #16 | 186 | 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 #32 | 188 | 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 #48 | 190 | 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 #16 | 196 | (~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 #16 | 202 | (~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 #32 | 205 | (~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 #32 | 208 | (~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 MOVKs | 222 | // MOVZ/MOVN and 1-3 MOVKs |
| 223 | int z = 0, m = 0; | 223 | int z = 0, m = 0; |
| 224 | uint32_t mov1 = 0xd2800000; // movz | 224 | 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; // movn | 232 | 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 : // nop | 257 | write32le(ptr, (a - t == 4 ? ARM64_NOP : |
| 258 | 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b | 258 | 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 offset | 295 | arm64_movimm(30, off); |
| 297 | o(0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30 | 296 | 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 offset | 331 | 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 offset | 349 | 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, #sym | 479 | o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | r); // add xr, xr, #sym |
| 481 | #else | 480 | #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, #sym | 482 | 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 | #endif | 485 | #endif |
| 487 | if (addend) { | 486 | if (addend) { |
| 488 | // add xr, xr, #addend | 487 | // 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 #12 | 492 | // 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 addent | 500 | 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 address | 556 | 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 | else | 561 | 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).16b | 583 | // mov v(r).16b,v(svr).16b |
| 583 | else | 584 | 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 | else | 588 | 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 .+8 | 606 | 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_BCHECK | 695 | #ifdef CONFIG_TCC_BCHECK |
| 695 | vtop->r &= ~VT_MUSTBOUND; | 696 | vtop->r &= ~VT_MUSTBOUND; |
| 696 | #endif | 697 | #endif |
| 697 | o(0xd61f0000 | (uint32_t)!b << 21 | intr(gv(RC_R30)) << 5); // br/blr | 698 | 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); // bl | 709 | o(ARM64_BL); // bl |
| 709 | } | 710 | } |
| 710 | 711 | ||
| 711 | static void gen_bounds_prolog(void) | 712 | static 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 | ||
| 723 | static void gen_bounds_epilog(void) | 724 | static 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_PE | 1435 | #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)] // ap | 1447 | 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,#216 | 1450 | 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_offs | 1482 | 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 .+20 | 1489 | o(0x540000ad); // b.le .+20 |
| 1488 | #endif | 1490 | #endif |
| 1489 | o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack | 1491 | |
| 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),#15 | 1494 | o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15 |
| 1492 | o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16 | 1495 | 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)] // __stack | 1498 | 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 .+16 | 1501 | o(ARM64_B | 4); // b .+16 |
| 1498 | o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs | 1502 | 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_top | 1503 | 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,sxtw | 1504 | o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw |
| 1501 | #endif | 1505 | #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 lab1 | 1517 | b1 = ind; o(0x5400000d); // b.le lab1 |
| 1513 | #endif | 1518 | #endif |
| 1514 | o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack | 1519 | 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),#15 | 1521 | o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15 |
| 1517 | o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16 | 1522 | 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)] // __stack | 1525 | 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 lab2 | 1527 | 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_offs | 1530 | 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 | #endif | 1550 | #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 | else | 1600 | 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); // nop | 1643 | 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 | |||
| 1654 | ST_FUNC void gjmp_addr(int a) | 1659 | ST_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 | ||
| 1660 | ST_FUNC int gjmp_append(int n, int t) | 1665 | ST_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 x30 | 1770 | 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, #1 | 2208 | 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),#1 | 2242 | 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); // b | 2244 | 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 lab1 | 2250 | o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1 |
| 2246 | o(0xd5033b9f); // dsb ish | 2251 | o(0xd5033b9f); // dsb ish |
| 2247 | o(0x51000400 | p | isz << 5); // sub w(p),w(isz),#1 | 2252 | 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); // b | 2254 | 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 lab1 | 2260 | o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1 |
| 2256 | o(0xd5033b9f); // dsb ish | 2261 | o(0xd5033b9f); // dsb ish |
| @@ -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 x17 | 142 | write32le(p + 16, ARM64_BR | ARM64_RN(17)); // br x17 |
| 142 | write32le(p + 20, 0xd503201f); // nop | 143 | write32le(p + 20, ARM64_NOP); // nop |
| 143 | write32le(p + 24, 0xd503201f); // nop | 144 | write32le(p + 24, ARM64_NOP); // nop |
| 144 | write32le(p + 28, 0xd503201f); // nop | 145 | 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 x17 | 160 | write32le(p + 12, ARM64_BR | ARM64_RN(17)); // br x17 |
| 160 | p += 16; | 161 | p += 16; |
| 161 | } | 162 | } |
| 162 | } | 163 | } |