aboutsummaryrefslogtreecommitdiff
path: root/src/host/buildvm_asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/host/buildvm_asm.c')
-rw-r--r--src/host/buildvm_asm.c67
1 files changed, 56 insertions, 11 deletions
diff --git a/src/host/buildvm_asm.c b/src/host/buildvm_asm.c
index 81a3969a..43595b31 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. */
55static void emit_asm_reloc_mach(BuildCtx *ctx, uint8_t *cp, int n, 55static 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
@@ -117,6 +144,14 @@ static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n,
117 fprintf(ctx->fp, "\t%s %d, %d, " TOCPREFIX "%s\n", 144 fprintf(ctx->fp, "\t%s %d, %d, " TOCPREFIX "%s\n",
118 (ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym); 145 (ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym);
119 } else if ((ins >> 26) == 18) { 146 } else if ((ins >> 26) == 18) {
147#if LJ_ARCH_PPC64
148 const char *suffix = strchr(sym, '@');
149 if (suffix && suffix[1] == 'h') {
150 fprintf(ctx->fp, "\taddis 11, 2, %s\n", sym);
151 } else if (suffix && suffix[1] == 'l') {
152 fprintf(ctx->fp, "\tld 12, %s\n", sym);
153 } else
154#endif
120 fprintf(ctx->fp, "\t%s " TOCPREFIX "%s\n", (ins & 1) ? "bl" : "b", sym); 155 fprintf(ctx->fp, "\t%s " TOCPREFIX "%s\n", (ins & 1) ? "bl" : "b", sym);
121 } else { 156 } else {
122 fprintf(stderr, 157 fprintf(stderr,
@@ -215,6 +250,9 @@ void emit_asm(BuildCtx *ctx)
215 int i, rel; 250 int i, rel;
216 251
217 fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch); 252 fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch);
253#if LJ_ARCH_PPC64
254 fprintf(ctx->fp, "\t.abiversion 2\n");
255#endif
218 fprintf(ctx->fp, "\t.text\n"); 256 fprintf(ctx->fp, "\t.text\n");
219 emit_asm_align(ctx, 4); 257 emit_asm_align(ctx, 4);
220 258
@@ -228,11 +266,20 @@ void emit_asm(BuildCtx *ctx)
228 266
229#if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND 267#if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND
230 /* This should really be moved into buildvm_arm.dasc. */ 268 /* This should really be moved into buildvm_arm.dasc. */
269#if LJ_ARCH_HASFPU
270 fprintf(ctx->fp,
271 ".fnstart\n"
272 ".save {r5, r6, r7, r8, r9, r10, r11, lr}\n"
273 ".vsave {d8-d15}\n"
274 ".save {r4}\n"
275 ".pad #28\n");
276#else
231 fprintf(ctx->fp, 277 fprintf(ctx->fp,
232 ".fnstart\n" 278 ".fnstart\n"
233 ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n" 279 ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
234 ".pad #28\n"); 280 ".pad #28\n");
235#endif 281#endif
282#endif
236#if LJ_TARGET_MIPS 283#if LJ_TARGET_MIPS
237 fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n"); 284 fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n");
238#endif 285#endif
@@ -255,8 +302,9 @@ void emit_asm(BuildCtx *ctx)
255 BuildReloc *r = &ctx->reloc[rel]; 302 BuildReloc *r = &ctx->reloc[rel];
256 int n = r->ofs - ofs; 303 int n = r->ofs - ofs;
257#if LJ_TARGET_X86ORX64 304#if LJ_TARGET_X86ORX64
258 if (ctx->mode == BUILD_machasm && r->type != 0) { 305 if (r->type != 0 &&
259 emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); 306 (ctx->mode == BUILD_elfasm || ctx->mode == BUILD_machasm)) {
307 emit_asm_reloc_text(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]);
260 } else { 308 } else {
261 emit_asm_bytes(ctx, ctx->code+ofs, n); 309 emit_asm_bytes(ctx, ctx->code+ofs, n);
262 emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); 310 emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]);
@@ -290,10 +338,7 @@ void emit_asm(BuildCtx *ctx)
290#if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA) 338#if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA)
291 fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); 339 fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n");
292#endif 340#endif
293#if LJ_TARGET_PPCSPE 341#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. */ 342 /* Hard-float ABI. */
298 fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n"); 343 fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n");
299#endif 344#endif