diff options
author | Mike Pall <mike> | 2012-06-09 15:04:03 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-06-09 15:12:44 +0200 |
commit | 9a9509c66a98d0bf42003ad5d06e8f275c5ff1f5 (patch) | |
tree | f5ca35d9ed7cc66f644828233f511f6db4634849 /src/buildvm_asm.c | |
parent | 0a6c8338d240dd318db2f5269414dcf7ddc9ed35 (diff) | |
download | luajit-9a9509c66a98d0bf42003ad5d06e8f275c5ff1f5.tar.gz luajit-9a9509c66a98d0bf42003ad5d06e8f275c5ff1f5.tar.bz2 luajit-9a9509c66a98d0bf42003ad5d06e8f275c5ff1f5.zip |
Reorganize build process.
Drop pre-translated buildvm_*.h.
Rename buildvm_*.dasc to vm_*.dasc.
Move buildvm* to host directory.
Build minilua, unless HOST_LUA is set.
Use HOST_LUA to run DynASM.
Translate only vm_*.dasc for target architecture.
Diffstat (limited to 'src/buildvm_asm.c')
-rw-r--r-- | src/buildvm_asm.c | 283 |
1 files changed, 0 insertions, 283 deletions
diff --git a/src/buildvm_asm.c b/src/buildvm_asm.c deleted file mode 100644 index f975eadc..00000000 --- a/src/buildvm_asm.c +++ /dev/null | |||
@@ -1,283 +0,0 @@ | |||
1 | /* | ||
2 | ** LuaJIT VM builder: Assembler source code emitter. | ||
3 | ** Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #include "buildvm.h" | ||
7 | #include "lj_bc.h" | ||
8 | |||
9 | /* ------------------------------------------------------------------------ */ | ||
10 | |||
11 | #if LJ_TARGET_X86ORX64 | ||
12 | /* Emit bytes piecewise as assembler text. */ | ||
13 | static void emit_asm_bytes(BuildCtx *ctx, uint8_t *p, int n) | ||
14 | { | ||
15 | int i; | ||
16 | for (i = 0; i < n; i++) { | ||
17 | if ((i & 15) == 0) | ||
18 | fprintf(ctx->fp, "\t.byte %d", p[i]); | ||
19 | else | ||
20 | fprintf(ctx->fp, ",%d", p[i]); | ||
21 | if ((i & 15) == 15) putc('\n', ctx->fp); | ||
22 | } | ||
23 | if ((n & 15) != 0) putc('\n', ctx->fp); | ||
24 | } | ||
25 | |||
26 | /* Emit relocation */ | ||
27 | static void emit_asm_reloc(BuildCtx *ctx, int type, const char *sym) | ||
28 | { | ||
29 | switch (ctx->mode) { | ||
30 | case BUILD_elfasm: | ||
31 | if (type) | ||
32 | fprintf(ctx->fp, "\t.long %s-.-4\n", sym); | ||
33 | else | ||
34 | fprintf(ctx->fp, "\t.long %s\n", sym); | ||
35 | break; | ||
36 | case BUILD_coffasm: | ||
37 | fprintf(ctx->fp, "\t.def %s; .scl 3; .type 32; .endef\n", sym); | ||
38 | if (type) | ||
39 | fprintf(ctx->fp, "\t.long %s-.-4\n", sym); | ||
40 | else | ||
41 | fprintf(ctx->fp, "\t.long %s\n", sym); | ||
42 | break; | ||
43 | default: /* BUILD_machasm for relative relocations handled below. */ | ||
44 | fprintf(ctx->fp, "\t.long %s\n", sym); | ||
45 | break; | ||
46 | } | ||
47 | } | ||
48 | |||
49 | static const char *const jccnames[] = { | ||
50 | "jo", "jno", "jb", "jnb", "jz", "jnz", "jbe", "ja", | ||
51 | "js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg" | ||
52 | }; | ||
53 | |||
54 | /* Emit relocation for the incredibly stupid OSX assembler. */ | ||
55 | static void emit_asm_reloc_mach(BuildCtx *ctx, uint8_t *cp, int n, | ||
56 | const char *sym) | ||
57 | { | ||
58 | const char *opname = NULL; | ||
59 | if (--n < 0) goto err; | ||
60 | if (cp[n] == 0xe8) { | ||
61 | opname = "call"; | ||
62 | } else if (cp[n] == 0xe9) { | ||
63 | opname = "jmp"; | ||
64 | } else if (cp[n] >= 0x80 && cp[n] <= 0x8f && n > 0 && cp[n-1] == 0x0f) { | ||
65 | opname = jccnames[cp[n]-0x80]; | ||
66 | n--; | ||
67 | } else { | ||
68 | err: | ||
69 | fprintf(stderr, "Error: unsupported opcode for %s symbol relocation.\n", | ||
70 | sym); | ||
71 | exit(1); | ||
72 | } | ||
73 | emit_asm_bytes(ctx, cp, n); | ||
74 | fprintf(ctx->fp, "\t%s %s\n", opname, sym); | ||
75 | } | ||
76 | #else | ||
77 | /* Emit words piecewise as assembler text. */ | ||
78 | static void emit_asm_words(BuildCtx *ctx, uint8_t *p, int n) | ||
79 | { | ||
80 | int i; | ||
81 | for (i = 0; i < n; i += 4) { | ||
82 | if ((i & 15) == 0) | ||
83 | fprintf(ctx->fp, "\t.long 0x%08x", *(uint32_t *)(p+i)); | ||
84 | else | ||
85 | fprintf(ctx->fp, ",0x%08x", *(uint32_t *)(p+i)); | ||
86 | if ((i & 15) == 12) putc('\n', ctx->fp); | ||
87 | } | ||
88 | if ((n & 15) != 0) putc('\n', ctx->fp); | ||
89 | } | ||
90 | |||
91 | /* Emit relocation as part of an instruction. */ | ||
92 | static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n, | ||
93 | const char *sym) | ||
94 | { | ||
95 | uint32_t ins; | ||
96 | emit_asm_words(ctx, p, n-4); | ||
97 | ins = *(uint32_t *)(p+n-4); | ||
98 | #if LJ_TARGET_ARM | ||
99 | if ((ins & 0xff000000u) == 0xfa000000u) { | ||
100 | fprintf(ctx->fp, "\tblx %s\n", sym); | ||
101 | } else if ((ins & 0x0e000000u) == 0x0a000000u) { | ||
102 | fprintf(ctx->fp, "\t%s%.2s %s\n", (ins & 0x01000000u) ? "bl" : "b", | ||
103 | "eqnecsccmiplvsvchilsgeltgtle" + 2*(ins >> 28), sym); | ||
104 | } else { | ||
105 | fprintf(stderr, | ||
106 | "Error: unsupported opcode %08x for %s symbol relocation.\n", | ||
107 | ins, sym); | ||
108 | exit(1); | ||
109 | } | ||
110 | #elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE | ||
111 | if ((ins >> 26) == 16) { | ||
112 | fprintf(ctx->fp, "\t%s %d, %d, %s\n", | ||
113 | (ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym); | ||
114 | } else if ((ins >> 26) == 18) { | ||
115 | fprintf(ctx->fp, "\t%s %s\n", (ins & 1) ? "bl" : "b", sym); | ||
116 | } else { | ||
117 | fprintf(stderr, | ||
118 | "Error: unsupported opcode %08x for %s symbol relocation.\n", | ||
119 | ins, sym); | ||
120 | exit(1); | ||
121 | } | ||
122 | #elif LJ_TARGET_MIPS | ||
123 | fprintf(stderr, | ||
124 | "Error: unsupported opcode %08x for %s symbol relocation.\n", | ||
125 | ins, sym); | ||
126 | exit(1); | ||
127 | #else | ||
128 | #error "missing relocation support for this architecture" | ||
129 | #endif | ||
130 | } | ||
131 | #endif | ||
132 | |||
133 | #if LJ_TARGET_ARM | ||
134 | #define ELFASM_PX "%%" | ||
135 | #else | ||
136 | #define ELFASM_PX "@" | ||
137 | #endif | ||
138 | |||
139 | /* Emit an assembler label. */ | ||
140 | static void emit_asm_label(BuildCtx *ctx, const char *name, int size, int isfunc) | ||
141 | { | ||
142 | switch (ctx->mode) { | ||
143 | case BUILD_elfasm: | ||
144 | fprintf(ctx->fp, | ||
145 | "\n\t.globl %s\n" | ||
146 | "\t.hidden %s\n" | ||
147 | "\t.type %s, " ELFASM_PX "%s\n" | ||
148 | "\t.size %s, %d\n" | ||
149 | "%s:\n", | ||
150 | name, name, name, isfunc ? "function" : "object", name, size, name); | ||
151 | break; | ||
152 | case BUILD_coffasm: | ||
153 | fprintf(ctx->fp, "\n\t.globl %s\n", name); | ||
154 | if (isfunc) | ||
155 | fprintf(ctx->fp, "\t.def %s; .scl 3; .type 32; .endef\n", name); | ||
156 | fprintf(ctx->fp, "%s:\n", name); | ||
157 | break; | ||
158 | case BUILD_machasm: | ||
159 | fprintf(ctx->fp, | ||
160 | "\n\t.private_extern %s\n" | ||
161 | "%s:\n", name, name); | ||
162 | break; | ||
163 | default: | ||
164 | break; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | /* Emit alignment. */ | ||
169 | static void emit_asm_align(BuildCtx *ctx, int bits) | ||
170 | { | ||
171 | switch (ctx->mode) { | ||
172 | case BUILD_elfasm: | ||
173 | case BUILD_coffasm: | ||
174 | fprintf(ctx->fp, "\t.p2align %d\n", bits); | ||
175 | break; | ||
176 | case BUILD_machasm: | ||
177 | fprintf(ctx->fp, "\t.align %d\n", bits); | ||
178 | break; | ||
179 | default: | ||
180 | break; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | /* ------------------------------------------------------------------------ */ | ||
185 | |||
186 | /* Emit assembler source code. */ | ||
187 | void emit_asm(BuildCtx *ctx) | ||
188 | { | ||
189 | int i, rel; | ||
190 | |||
191 | fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch); | ||
192 | fprintf(ctx->fp, "\t.text\n"); | ||
193 | emit_asm_align(ctx, 4); | ||
194 | |||
195 | emit_asm_label(ctx, ctx->beginsym, 0, 0); | ||
196 | if (ctx->mode != BUILD_machasm) | ||
197 | fprintf(ctx->fp, ".Lbegin:\n"); | ||
198 | |||
199 | #if LJ_TARGET_ARM && defined(__GNUC__) && !defined(LUAJIT_NO_UNWIND) | ||
200 | /* This should really be moved into buildvm_arm.dasc. */ | ||
201 | fprintf(ctx->fp, | ||
202 | ".fnstart\n" | ||
203 | ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n" | ||
204 | ".pad #28\n"); | ||
205 | #endif | ||
206 | #if LJ_TARGET_MIPS | ||
207 | fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n"); | ||
208 | #endif | ||
209 | |||
210 | for (i = rel = 0; i < ctx->nsym; i++) { | ||
211 | int32_t ofs = ctx->sym[i].ofs; | ||
212 | int32_t next = ctx->sym[i+1].ofs; | ||
213 | #if LJ_TARGET_ARM && defined(__GNUC__) && !defined(LUAJIT_NO_UNWIND) && \ | ||
214 | LJ_HASFFI | ||
215 | if (!strcmp(ctx->sym[i].name, "lj_vm_ffi_call")) | ||
216 | fprintf(ctx->fp, | ||
217 | ".globl lj_err_unwind_arm\n" | ||
218 | ".personality lj_err_unwind_arm\n" | ||
219 | ".fnend\n" | ||
220 | ".fnstart\n" | ||
221 | ".save {r4, r5, r11, lr}\n" | ||
222 | ".setfp r11, sp\n"); | ||
223 | #endif | ||
224 | emit_asm_label(ctx, ctx->sym[i].name, next - ofs, 1); | ||
225 | while (rel < ctx->nreloc && ctx->reloc[rel].ofs <= next) { | ||
226 | BuildReloc *r = &ctx->reloc[rel]; | ||
227 | int n = r->ofs - ofs; | ||
228 | #if LJ_TARGET_X86ORX64 | ||
229 | if (ctx->mode == BUILD_machasm && r->type != 0) { | ||
230 | emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | ||
231 | } else { | ||
232 | emit_asm_bytes(ctx, ctx->code+ofs, n); | ||
233 | emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); | ||
234 | } | ||
235 | ofs += n+4; | ||
236 | #else | ||
237 | emit_asm_wordreloc(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | ||
238 | ofs += n; | ||
239 | #endif | ||
240 | rel++; | ||
241 | } | ||
242 | #if LJ_TARGET_X86ORX64 | ||
243 | emit_asm_bytes(ctx, ctx->code+ofs, next-ofs); | ||
244 | #else | ||
245 | emit_asm_words(ctx, ctx->code+ofs, next-ofs); | ||
246 | #endif | ||
247 | } | ||
248 | |||
249 | #if LJ_TARGET_ARM && defined(__GNUC__) && !defined(LUAJIT_NO_UNWIND) | ||
250 | fprintf(ctx->fp, | ||
251 | #if !LJ_HASFFI | ||
252 | ".globl lj_err_unwind_arm\n" | ||
253 | ".personality lj_err_unwind_arm\n" | ||
254 | #endif | ||
255 | ".fnend\n"); | ||
256 | #endif | ||
257 | |||
258 | fprintf(ctx->fp, "\n"); | ||
259 | switch (ctx->mode) { | ||
260 | case BUILD_elfasm: | ||
261 | fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); | ||
262 | #if LJ_TARGET_PPCSPE | ||
263 | /* Soft-float ABI + SPE. */ | ||
264 | fprintf(ctx->fp, "\t.gnu_attribute 4, 2\n\t.gnu_attribute 8, 3\n"); | ||
265 | #elif LJ_TARGET_PPC | ||
266 | /* Hard-float ABI. */ | ||
267 | fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n"); | ||
268 | #endif | ||
269 | /* fallthrough */ | ||
270 | case BUILD_coffasm: | ||
271 | fprintf(ctx->fp, "\t.ident \"%s\"\n", ctx->dasm_ident); | ||
272 | break; | ||
273 | case BUILD_machasm: | ||
274 | fprintf(ctx->fp, | ||
275 | "\t.cstring\n" | ||
276 | "\t.ascii \"%s\\0\"\n", ctx->dasm_ident); | ||
277 | break; | ||
278 | default: | ||
279 | break; | ||
280 | } | ||
281 | fprintf(ctx->fp, "\n"); | ||
282 | } | ||
283 | |||