diff options
Diffstat (limited to 'src/host/buildvm_asm.c')
-rw-r--r-- | src/host/buildvm_asm.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/src/host/buildvm_asm.c b/src/host/buildvm_asm.c index 2cb7d451..b9cfa049 100644 --- a/src/host/buildvm_asm.c +++ b/src/host/buildvm_asm.c | |||
@@ -51,8 +51,8 @@ static const char *const jccnames[] = { | |||
51 | "js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg" | 51 | "js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg" |
52 | }; | 52 | }; |
53 | 53 | ||
54 | /* Emit relocation for the incredibly stupid OSX assembler. */ | 54 | /* Emit x86/x64 text relocations. */ |
55 | static void emit_asm_reloc_mach(BuildCtx *ctx, uint8_t *cp, int n, | 55 | static void emit_asm_reloc_text(BuildCtx *ctx, uint8_t *cp, int n, |
56 | const char *sym) | 56 | const char *sym) |
57 | { | 57 | { |
58 | const char *opname = NULL; | 58 | const char *opname = NULL; |
@@ -71,6 +71,20 @@ err: | |||
71 | exit(1); | 71 | exit(1); |
72 | } | 72 | } |
73 | emit_asm_bytes(ctx, cp, n); | 73 | emit_asm_bytes(ctx, cp, n); |
74 | if (strncmp(sym+(*sym == '_'), LABEL_PREFIX, sizeof(LABEL_PREFIX)-1)) { | ||
75 | /* Various fixups for external symbols outside of our binary. */ | ||
76 | if (ctx->mode == BUILD_elfasm) { | ||
77 | if (LJ_32) | ||
78 | fprintf(ctx->fp, "#if __PIC__\n\t%s lj_wrap_%s\n#else\n", opname, sym); | ||
79 | fprintf(ctx->fp, "\t%s %s@PLT\n", opname, sym); | ||
80 | if (LJ_32) | ||
81 | fprintf(ctx->fp, "#endif\n"); | ||
82 | return; | ||
83 | } else if (LJ_32 && ctx->mode == BUILD_machasm) { | ||
84 | fprintf(ctx->fp, "\t%s L%s$stub\n", opname, sym); | ||
85 | return; | ||
86 | } | ||
87 | } | ||
74 | fprintf(ctx->fp, "\t%s %s\n", opname, sym); | 88 | fprintf(ctx->fp, "\t%s %s\n", opname, sym); |
75 | } | 89 | } |
76 | #else | 90 | #else |
@@ -79,10 +93,14 @@ static void emit_asm_words(BuildCtx *ctx, uint8_t *p, int n) | |||
79 | { | 93 | { |
80 | int i; | 94 | int i; |
81 | for (i = 0; i < n; i += 4) { | 95 | for (i = 0; i < n; i += 4) { |
96 | uint32_t ins = *(uint32_t *)(p+i); | ||
97 | #if LJ_TARGET_ARM64 && LJ_BE | ||
98 | ins = lj_bswap(ins); /* ARM64 instructions are always little-endian. */ | ||
99 | #endif | ||
82 | if ((i & 15) == 0) | 100 | if ((i & 15) == 0) |
83 | fprintf(ctx->fp, "\t.long 0x%08x", *(uint32_t *)(p+i)); | 101 | fprintf(ctx->fp, "\t.long 0x%08x", ins); |
84 | else | 102 | else |
85 | fprintf(ctx->fp, ",0x%08x", *(uint32_t *)(p+i)); | 103 | fprintf(ctx->fp, ",0x%08x", ins); |
86 | if ((i & 15) == 12) putc('\n', ctx->fp); | 104 | if ((i & 15) == 12) putc('\n', ctx->fp); |
87 | } | 105 | } |
88 | if ((n & 15) != 0) putc('\n', ctx->fp); | 106 | if ((n & 15) != 0) putc('\n', ctx->fp); |
@@ -107,7 +125,16 @@ static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n, | |||
107 | ins, sym); | 125 | ins, sym); |
108 | exit(1); | 126 | exit(1); |
109 | } | 127 | } |
110 | #elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE | 128 | #elif LJ_TARGET_ARM64 |
129 | if ((ins >> 26) == 0x25u) { | ||
130 | fprintf(ctx->fp, "\tbl %s\n", sym); | ||
131 | } else { | ||
132 | fprintf(stderr, | ||
133 | "Error: unsupported opcode %08x for %s symbol relocation.\n", | ||
134 | ins, sym); | ||
135 | exit(1); | ||
136 | } | ||
137 | #elif LJ_TARGET_PPC | ||
111 | #if LJ_TARGET_PS3 | 138 | #if LJ_TARGET_PS3 |
112 | #define TOCPREFIX "." | 139 | #define TOCPREFIX "." |
113 | #else | 140 | #else |
@@ -228,11 +255,20 @@ void emit_asm(BuildCtx *ctx) | |||
228 | 255 | ||
229 | #if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND | 256 | #if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND |
230 | /* This should really be moved into buildvm_arm.dasc. */ | 257 | /* This should really be moved into buildvm_arm.dasc. */ |
258 | #if LJ_ARCH_HASFPU | ||
259 | fprintf(ctx->fp, | ||
260 | ".fnstart\n" | ||
261 | ".save {r5, r6, r7, r8, r9, r10, r11, lr}\n" | ||
262 | ".vsave {d8-d15}\n" | ||
263 | ".save {r4}\n" | ||
264 | ".pad #28\n"); | ||
265 | #else | ||
231 | fprintf(ctx->fp, | 266 | fprintf(ctx->fp, |
232 | ".fnstart\n" | 267 | ".fnstart\n" |
233 | ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n" | 268 | ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n" |
234 | ".pad #28\n"); | 269 | ".pad #28\n"); |
235 | #endif | 270 | #endif |
271 | #endif | ||
236 | #if LJ_TARGET_MIPS | 272 | #if LJ_TARGET_MIPS |
237 | fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n"); | 273 | fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n"); |
238 | #endif | 274 | #endif |
@@ -255,8 +291,9 @@ void emit_asm(BuildCtx *ctx) | |||
255 | BuildReloc *r = &ctx->reloc[rel]; | 291 | BuildReloc *r = &ctx->reloc[rel]; |
256 | int n = r->ofs - ofs; | 292 | int n = r->ofs - ofs; |
257 | #if LJ_TARGET_X86ORX64 | 293 | #if LJ_TARGET_X86ORX64 |
258 | if (ctx->mode == BUILD_machasm && r->type != 0) { | 294 | if (r->type != 0 && |
259 | emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | 295 | (ctx->mode == BUILD_elfasm || ctx->mode == BUILD_machasm)) { |
296 | emit_asm_reloc_text(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | ||
260 | } else { | 297 | } else { |
261 | emit_asm_bytes(ctx, ctx->code+ofs, n); | 298 | emit_asm_bytes(ctx, ctx->code+ofs, n); |
262 | emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); | 299 | emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); |
@@ -290,10 +327,7 @@ void emit_asm(BuildCtx *ctx) | |||
290 | #if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA) | 327 | #if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA) |
291 | fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); | 328 | fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); |
292 | #endif | 329 | #endif |
293 | #if LJ_TARGET_PPCSPE | 330 | #if LJ_TARGET_PPC && !LJ_TARGET_PS3 && !LJ_ABI_SOFTFP |
294 | /* Soft-float ABI + SPE. */ | ||
295 | fprintf(ctx->fp, "\t.gnu_attribute 4, 2\n\t.gnu_attribute 8, 3\n"); | ||
296 | #elif LJ_TARGET_PPC && !LJ_TARGET_PS3 | ||
297 | /* Hard-float ABI. */ | 331 | /* Hard-float ABI. */ |
298 | fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n"); | 332 | fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n"); |
299 | #endif | 333 | #endif |