diff options
Diffstat (limited to 'src/host/buildvm_asm.c')
-rw-r--r-- | src/host/buildvm_asm.c | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/src/host/buildvm_asm.c b/src/host/buildvm_asm.c index 458ce733..e7c5de70 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 |
@@ -216,6 +243,12 @@ void emit_asm(BuildCtx *ctx) | |||
216 | 243 | ||
217 | fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch); | 244 | fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch); |
218 | fprintf(ctx->fp, "\t.text\n"); | 245 | fprintf(ctx->fp, "\t.text\n"); |
246 | #if LJ_TARGET_MIPS32 && !LJ_ABI_SOFTFP | ||
247 | fprintf(ctx->fp, "\t.module fp=32\n"); | ||
248 | #endif | ||
249 | #if LJ_TARGET_MIPS | ||
250 | fprintf(ctx->fp, "\t.set nomips16\n\t.abicalls\n\t.set noreorder\n\t.set nomacro\n"); | ||
251 | #endif | ||
219 | emit_asm_align(ctx, 4); | 252 | emit_asm_align(ctx, 4); |
220 | 253 | ||
221 | #if LJ_TARGET_PS3 | 254 | #if LJ_TARGET_PS3 |
@@ -228,13 +261,19 @@ void emit_asm(BuildCtx *ctx) | |||
228 | 261 | ||
229 | #if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND | 262 | #if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND |
230 | /* This should really be moved into buildvm_arm.dasc. */ | 263 | /* This should really be moved into buildvm_arm.dasc. */ |
264 | #if LJ_ARCH_HASFPU | ||
265 | fprintf(ctx->fp, | ||
266 | ".fnstart\n" | ||
267 | ".save {r5, r6, r7, r8, r9, r10, r11, lr}\n" | ||
268 | ".vsave {d8-d15}\n" | ||
269 | ".save {r4}\n" | ||
270 | ".pad #28\n"); | ||
271 | #else | ||
231 | fprintf(ctx->fp, | 272 | fprintf(ctx->fp, |
232 | ".fnstart\n" | 273 | ".fnstart\n" |
233 | ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n" | 274 | ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n" |
234 | ".pad #28\n"); | 275 | ".pad #28\n"); |
235 | #endif | 276 | #endif |
236 | #if LJ_TARGET_MIPS | ||
237 | fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n"); | ||
238 | #endif | 277 | #endif |
239 | 278 | ||
240 | for (i = rel = 0; i < ctx->nsym; i++) { | 279 | for (i = rel = 0; i < ctx->nsym; i++) { |
@@ -255,8 +294,9 @@ void emit_asm(BuildCtx *ctx) | |||
255 | BuildReloc *r = &ctx->reloc[rel]; | 294 | BuildReloc *r = &ctx->reloc[rel]; |
256 | int n = r->ofs - ofs; | 295 | int n = r->ofs - ofs; |
257 | #if LJ_TARGET_X86ORX64 | 296 | #if LJ_TARGET_X86ORX64 |
258 | if (ctx->mode == BUILD_machasm && r->type != 0) { | 297 | if (r->type != 0 && |
259 | emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | 298 | (ctx->mode == BUILD_elfasm || ctx->mode == BUILD_machasm)) { |
299 | emit_asm_reloc_text(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | ||
260 | } else { | 300 | } else { |
261 | emit_asm_bytes(ctx, ctx->code+ofs, n); | 301 | emit_asm_bytes(ctx, ctx->code+ofs, n); |
262 | emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); | 302 | emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); |
@@ -290,10 +330,7 @@ void emit_asm(BuildCtx *ctx) | |||
290 | #if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA) | 330 | #if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA) |
291 | fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); | 331 | fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); |
292 | #endif | 332 | #endif |
293 | #if LJ_TARGET_PPCSPE | 333 | #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. */ | 334 | /* Hard-float ABI. */ |
298 | fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n"); | 335 | fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n"); |
299 | #endif | 336 | #endif |