aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorWojciech Kosior <kwojtus@protonmail.com>2020-10-08 19:18:43 +0200
committerWojciech Kosior <kwojtus@protonmail.com>2020-10-08 19:18:43 +0200
commit5e04a9626e2986fc40825d15cb09a274223381e9 (patch)
treea52a96fa585247145cb521b9c6f7fe7946ba7997 /tools
parent63a2cced4238af7d171e0b8807d887c435b4656b (diff)
downloadAGH-engineering-thesis-5e04a9626e2986fc40825d15cb09a274223381e9.tar.gz
AGH-engineering-thesis-5e04a9626e2986fc40825d15cb09a274223381e9.zip
translate webasm block of instructions + put instruction names as comments in generated code
Diffstat (limited to 'tools')
-rw-r--r--tools/assemble.c38
-rw-r--r--tools/parse_module.c2
-rw-r--r--tools/stack_machine_instruction.h7
-rw-r--r--tools/translate.c35
-rw-r--r--tools/translate_xmacro.h1
-rw-r--r--tools/wasm.h1
-rw-r--r--tools/wasm_compile.c26
-rw-r--r--tools/wasm_compile.h12
8 files changed, 79 insertions, 43 deletions
diff --git a/tools/assemble.c b/tools/assemble.c
index b8bd75e..bb8c8d4 100644
--- a/tools/assemble.c
+++ b/tools/assemble.c
@@ -20,7 +20,7 @@ void free_expr(struct instruction *expr)
/* instructions are stored in a circular list */
int add_instruction(struct instruction **expr, uint16_t encoding,
- struct instruction_data data)
+ struct instruction_data data, const char *name)
{
struct instruction *new;
@@ -34,6 +34,7 @@ int add_instruction(struct instruction **expr, uint16_t encoding,
new->address_assigned = false;
new->encoding = encoding;
new->data = data;
+ new->name = name;
if (!*expr) {
new->next = new;
@@ -113,11 +114,13 @@ static uint16_t im_instruction(uint16_t payload)
}
static void encode_instruction(struct instruction *instruction,
- uint16_t *memory)
+ struct translated_word *memory)
{
uint32_t im = 0;
uint16_t encoding = instruction->encoding;
- uint16_t *dest = memory + instruction->address / 2;
+ struct translated_word *dest = memory + instruction->address / 2;
+
+ dest->instr = instruction;
if (instruction->data.info == DATA_INSTR_ADDR) {
im = (*instruction->data.data.ptr)->address;
@@ -132,17 +135,18 @@ static void encode_instruction(struct instruction *instruction,
case DATA_INSTR_ADDR :
case DATA_ADDR_AFTER :
case DATA_KNOWN :
- *(dest++) = im_instruction(im >> 22);
+ (dest++)->contents = im_instruction(im >> 22);
case DATA_KNOWN_21_BITS :
- *(dest++) = im_instruction(im >> 7);
+ (dest++)->contents = im_instruction(im >> 7);
case DATA_KNOWN_6_BITS :
encoding |= im & 0x7F;
}
- *dest = encoding;
+ dest->contents = encoding;
}
-static void encode_expr(struct instruction *expr, uint16_t *memory)
+static void encode_expr(struct instruction *expr,
+ struct translated_word *memory)
{
struct instruction *tmp = expr;
@@ -152,14 +156,14 @@ static void encode_expr(struct instruction *expr, uint16_t *memory)
} while (tmp != expr);
}
-int assemble(uint32_t memory_size, uint16_t memory[memory_size],
+int assemble(uint32_t memory_size, struct translated_word memory[memory_size],
struct module *module)
{
uint32_t i;
struct function *main_function = NULL;
uint32_t current_address;
uint64_t function_size;
- struct instruction *startup = NULL;
+ struct instruction **startup = &module->startup;
unsigned short startup_size;
int retval = -1;
@@ -181,13 +185,13 @@ int assemble(uint32_t memory_size, uint16_t memory[memory_size],
* We're first writing some value at STACK_FRAME_BACKUP_ADDR to be able
* to check, if the functions we call restore frame address properly
*/
- if (i_const(im(0x23), &startup) ||
- i_store(im(STACK_FRAME_BACKUP_ADDR), &startup) ||
- i_call (ptr(&main_function->translated_body), &startup) ||
- i_halt ( &startup))
+ if (i_const(im(0x23), startup) ||
+ i_store(im(STACK_FRAME_BACKUP_ADDR), startup) ||
+ i_call (ptr(&main_function->translated_body), startup) ||
+ i_halt ( startup))
goto fail;
- startup_size = estimate_expr_size(startup);
+ startup_size = estimate_expr_size(*startup);
i = module->functions_count;
current_address = CODE_TOP_ADDR;
@@ -209,13 +213,13 @@ int assemble(uint32_t memory_size, uint16_t memory[memory_size],
assign_addresses_and_sizes(module->functions[i].translated_body,
module->functions[i].start_addr);
- assign_addresses_and_sizes(startup, 0x0);
+ assign_addresses_and_sizes(*startup, 0x0);
i = module->functions_count;
while (i--)
encode_expr(module->functions[i].translated_body, memory);
- encode_expr(startup, memory);
+ encode_expr(*startup, memory);
retval = 0;
@@ -223,7 +227,5 @@ fail:
if (retval)
PRERR("Couldn't assemble code for stack machine\n");
- free_expr(startup);
-
return retval;
}
diff --git a/tools/parse_module.c b/tools/parse_module.c
index 3f9895c..8c519ab 100644
--- a/tools/parse_module.c
+++ b/tools/parse_module.c
@@ -84,6 +84,8 @@ void free_module(struct module *module)
free_targets(module->targets);
+ free_expr(module->startup);
+
free(module);
}
diff --git a/tools/stack_machine_instruction.h b/tools/stack_machine_instruction.h
index 1f47c40..15c870b 100644
--- a/tools/stack_machine_instruction.h
+++ b/tools/stack_machine_instruction.h
@@ -23,6 +23,7 @@ struct instruction {
bool address_assigned;
uint16_t encoding;
struct instruction_data data;
+ const char *name;
};
#define NO_DATA ((struct instruction_data) { \
@@ -76,21 +77,21 @@ inline static struct instruction_data ptr_after(struct instruction **val) {
}
int add_instruction(struct instruction **expr, uint16_t encoding,
- struct instruction_data data);
+ struct instruction_data data, const char *name);
/* Define stack machine instructions, that take immediate operands */
#define X(instr, encoding) \
inline static int i_##instr(struct instruction_data data, \
struct instruction **expr) \
{ \
- return add_instruction(expr, encoding, data); \
+ return add_instruction(expr, encoding, data, #instr); \
}
/* Define stack machine instructions, that *don't* take immediate operands */
#define Y(instr, encoding) \
inline static int i_##instr(struct instruction **expr) \
{ \
- return add_instruction(expr, encoding, NO_DATA); \
+ return add_instruction(expr, encoding, NO_DATA, #instr); \
}
X(store, 0x7E00) /* 0111_1110_0xxx_xxxx */
diff --git a/tools/translate.c b/tools/translate.c
index 27532ad..00191a3 100644
--- a/tools/translate.c
+++ b/tools/translate.c
@@ -276,7 +276,7 @@ static int typecheck_local_get_set(struct translation *data, uint32_t localidx,
/* Translate complex - those routines have to be defined manually */
#define TC(wasm_opcode, name, argtypes, restype)
-static int _translate_loop(struct translation *data)
+static int translate_block_loop(struct translation *data, bool loop)
{
struct resulttype block_args, block_results;
char type_storage;
@@ -291,7 +291,7 @@ static int _translate_loop(struct translation *data)
goto fail;
if (translate_expr(data, &block_args, &block_results,
- &loop_end_markers, NULL, true))
+ &loop_end_markers, NULL, loop))
goto fail;
return 0;
@@ -301,6 +301,16 @@ fail:
return -1;
}
+static int _translate_block(struct translation *data)
+{
+ return translate_block_loop(data, false);
+}
+
+static int _translate_loop(struct translation *data)
+{
+ return translate_block_loop(data, true);
+}
+
static int _translate_if(struct translation *data)
{
struct types *backed_stack;
@@ -343,7 +353,7 @@ static int _translate_if(struct translation *data)
data->types_stack = backed_stack;
if (retval)
- goto fail;
+ goto fail;
if (i_jump(ptr_after(&else_end->instr), expr))
goto fail;
@@ -422,7 +432,7 @@ static int _translate_br(struct translation *data)
i_load_p(im(-4 * (offset_dst - 1)), expr) ||
i_swap ( expr) ||
i_load_p(im(-4 * offset_dst), expr) ||
- i_add_sp(im(-4 * (shift + 2)), expr))
+ i_add_sp(im(4 * (shift + 2)), expr))
goto fail;
for (i = 0; i < arity; i++) {
@@ -615,11 +625,11 @@ static int translate_load_store(struct translation *data,
/** DEFINE TRANSLATION FUNCTIONS POINTER ARRAY **/
/* Translate complex */
-#define TC(wasm_opcode, name, argtypes, restype) \
+#define TC(wasm_opcode, name, argtypes, restype) \
[wasm_opcode] = _translate_##name,
/* Translate Simple */
-#define TS(wasm_opcode, sm_instr, argtypes, restype) \
+#define TS(wasm_opcode, sm_instr, argtypes, restype) \
TC(wasm_opcode, sm_instr, dummy, dummy)
/* Translate load/store */
@@ -734,6 +744,7 @@ static struct target *add_target(struct module *module)
}
static struct label *add_label(struct translation *data, struct target *target,
+ uint32_t values_popped,
struct resulttype *arity)
{
struct label *lbl;
@@ -750,6 +761,7 @@ static struct label *add_label(struct translation *data, struct target *target,
lbl->arity = arity;
lbl->values_on_stack = data->labels ? data->labels->values_on_stack : 0;
lbl->values_on_stack += stack_size(data->types_stack);
+ lbl->values_on_stack -= values_popped;
data->labels = lbl;
@@ -777,7 +789,7 @@ static int translate_expr(struct translation *data, struct resulttype *args,
if (continuation_at_start)
continuation->instr = data->function->translated_body->prev;
- label = add_label(data, continuation,
+ label = add_label(data, continuation, args ? args->count : 0,
continuation_at_start ? args : results);
if (!label)
@@ -918,9 +930,11 @@ int translate(FILE *handle, struct function *function, struct module *module)
goto fail;
/* function epilogue */
+ if (i_load (im(STACK_FRAME_BACKUP_ADDR), expr))
+ goto fail;
+
if (function->type->results.count) {
- if (i_load (im(STACK_FRAME_BACKUP_ADDR), expr) ||
- i_swap ( expr) ||
+ if (i_swap ( expr) ||
i_store_p(im(4 * (2 + all_locals_count - 1)), expr) ||
i_load (im(STACK_FRAME_BACKUP_ADDR), expr) ||
i_tee ( expr) ||
@@ -932,8 +946,7 @@ int translate(FILE *handle, struct function *function, struct module *module)
goto fail;
} else {
/* It's a bit shorter if we don't return anything */
- if (i_load (im(STACK_FRAME_BACKUP_ADDR), expr) ||
- i_tee ( expr) ||
+ if (i_tee ( expr) ||
i_tee ( expr) ||
i_load_p (im(4 * (1 + locals_count)), expr) ||
i_store_p(im(4 * (2 + all_locals_count - 1)), expr) ||
diff --git a/tools/translate_xmacro.h b/tools/translate_xmacro.h
index 079fc74..e906261 100644
--- a/tools/translate_xmacro.h
+++ b/tools/translate_xmacro.h
@@ -24,6 +24,7 @@ TLS(WASM_I32_STORE16, storew_p, i32_i32, empty)
* There are more checks to be performed in case of if and br_if, but we do them
* another way and only check for the i32 condition value here.
*/
+TC (WASM_BLOCK, block, custom, custom)
TC (WASM_LOOP, loop, custom, custom)
TC (WASM_IF, if, i32, custom)
TC (WASM_BR, br, custom, custom)
diff --git a/tools/wasm.h b/tools/wasm.h
index 8333ce5..afa1908 100644
--- a/tools/wasm.h
+++ b/tools/wasm.h
@@ -22,6 +22,7 @@
#define EXPORT_GLOBALIDX 0x03
/* WebAssembly opcodes */
+#define WASM_BLOCK 0x02
#define WASM_LOOP 0x03
#define WASM_IF 0x04
#define WASM_ELSE 0x05
diff --git a/tools/wasm_compile.c b/tools/wasm_compile.c
index 64988c8..c455541 100644
--- a/tools/wasm_compile.c
+++ b/tools/wasm_compile.c
@@ -1,24 +1,33 @@
#include "wasm_compile.h"
+#include "stack_machine_instruction.h"
-void print_instructions(uint32_t count, uint16_t instructions[count])
+void print_instructions(uint32_t count,
+ struct translated_word memory[count])
{
uint32_t i;
char binary[17];
- uint16_t instruction;
+ uint16_t bits;
int j;
binary[16] = '\0';
for (i = 0; i < count; i++) {
- instruction = instructions[i];
+ bits = memory[i].contents;
j = 16;
while (j--) {
- binary[j] = (instruction & 1) ? '1' : '0';
- instruction >>= 1;
+ binary[j] = (bits & 1) ? '1' : '0';
+ bits >>= 1;
}
- puts(binary);
+ printf(binary);
+
+ if (memory[i].instr) {
+ printf(" // 0x%03lx %s", (long) i,
+ memory[i].instr->name);
+ }
+
+ putchar('\n');
}
}
@@ -26,7 +35,7 @@ int main(int argc, char **argv)
{
FILE *handle = NULL;
struct module *module = NULL;
- uint16_t *translated_instructions = NULL;
+ struct translated_word *translated_instructions = NULL;
char retval = -1;
if (argc < 2) {
@@ -46,7 +55,8 @@ int main(int argc, char **argv)
if (!module)
goto fail;
- translated_instructions = calloc(1, CODE_TOP_ADDR);
+ translated_instructions = calloc(1, CODE_TOP_ADDR *
+ sizeof(struct translated_word));
if (!translated_instructions) {
PRERR(MSG_ALLOC_FAIL(CODE_TOP_ADDR));
diff --git a/tools/wasm_compile.h b/tools/wasm_compile.h
index 4cee1bb..c5ff49c 100644
--- a/tools/wasm_compile.h
+++ b/tools/wasm_compile.h
@@ -11,8 +11,8 @@
#define STACK_FRAME_BACKUP_ADDR 0x0FFFFC
#define STACK_TOP_ADDR 0x0FFFFC
#define CODE_BOTTOM_ADDR 0x000000
-#define CODE_TOP_ADDR 0x000200
-#define MEMORY_BOTTOM_ADDR 0x000200
+#define CODE_TOP_ADDR 0x000400
+#define MEMORY_BOTTOM_ADDR 0x000400
/* Error messages */
#define MSG_SIZE_OVERFLOW "Number overflows size_t\n"
@@ -70,6 +70,12 @@ struct module {
uint32_t exports_count;
struct export *exports;
struct target *targets;
+ struct instruction *startup;
+};
+
+struct translated_word {
+ uint16_t contents;
+ struct instruction *instr;
};
int leb_32(FILE *handle, uint32_t *result, bool with_sign);
@@ -94,7 +100,7 @@ struct module *parse_module(FILE *handle);
int translate(FILE *handle, struct function *function, struct module *module);
-int assemble(uint32_t memory_size, uint16_t memory[memory_size],
+int assemble(uint32_t memory_size, struct translated_word memory[memory_size],
struct module *module);
#endif /* WASM_COMPILE_H */