diff options
-rw-r--r-- | gas/ChangeLog | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/wasm32/allinsn.d | 4 | ||||
-rw-r--r-- | opcodes/ChangeLog | 7 | ||||
-rw-r--r-- | opcodes/wasm32-dis.c | 445 |
4 files changed, 249 insertions, 211 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 4186fbd..c6f93cc 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,9 @@ 2020-01-13 Alan Modra <amodra@gmail.com> + * testsuite/gas/wasm32/allinsn.d: Update expected output. + +2020-01-13 Alan Modra <amodra@gmail.com> + * config/tc-tic4x.c (tic4x_operands_match): Correct tic3x trap insertion. diff --git a/gas/testsuite/gas/wasm32/allinsn.d b/gas/testsuite/gas/wasm32/allinsn.d index c594c72..4429385 100644 --- a/gas/testsuite/gas/wasm32/allinsn.d +++ b/gas/testsuite/gas/wasm32/allinsn.d @@ -20,7 +20,7 @@ Disassembly of section .text: 12: 8b f32.abs 13: 92 f32.add 14: 8d f32.ceil - 15: 43 d0 0f 49 f32.const 3.141590118408203125 + 15: 43 d0 0f 49 f32.const 3.14159012 19: 40 1a: b2 f32.convert_s/i32 1b: b4 f32.convert_s/i64 @@ -50,7 +50,7 @@ Disassembly of section .text: 37: 99 f64.abs 38: a0 f64.add 39: 9b f64.ceil - 3a: 44 97 5f 4f f64.const 3.14158999999999976088e\+200 + 3a: 44 97 5f 4f f64.const 3.1415899999999998e\+200 3e: fd bc 6a 90 42: 69 43: b7 f64.convert_s/i32 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index e034a61..4584331 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,5 +1,12 @@ 2020-01-13 Alan Modra <amodra@gmail.com> + * wasm32-dis.c (print_insn_wasm32): Localise variables. Store + result of wasm_read_leb128 in a uint64_t and check that bits + are not lost when copying to other locals. Use uint32_t for + most locals. Use PRId64 when printing int64_t. + +2020-01-13 Alan Modra <amodra@gmail.com> + * score-dis.c: Formatting. * score7-dis.c: Formatting. diff --git a/opcodes/wasm32-dis.c b/opcodes/wasm32-dis.c index aea93b8..946ce5f 100644 --- a/opcodes/wasm32-dis.c +++ b/opcodes/wasm32-dis.c @@ -271,33 +271,10 @@ print_insn_wasm32 (bfd_vma pc, struct disassemble_info *info) void *stream = info->stream; fprintf_ftype prin = info->fprintf_func; struct wasm32_private_data *private_data = info->private_data; - long long constant = 0; - double fconstant = 0.0; - long flags = 0; - long offset = 0; - long depth = 0; - long function_index = 0; - long target_count = 0; - long block_type = 0; - int len = 1; - int ret = 0; - unsigned int bytes_read = 0; - int i; - const char *locals[] = - { - "$dpc", "$sp1", "$r0", "$r1", "$rpc", "$pc0", - "$rp", "$fp", "$sp", - "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", - "$i0", "$i1", "$i2", "$i3", "$i4", "$i5", "$i6", "$i7", - "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", - }; - int nlocals = ARRAY_SIZE (locals); - const char *globals[] = - { - "$got", "$plt", "$gpo" - }; - int nglobals = ARRAY_SIZE (globals); - bfd_boolean error = FALSE; + uint64_t val; + int len; + unsigned int bytes_read; + bfd_boolean error; if (info->read_memory_func (pc, buffer, 1, info)) return -1; @@ -313,189 +290,239 @@ print_insn_wasm32 (bfd_vma pc, struct disassemble_info *info) prin (stream, "\t.byte 0x%02x\n", buffer[0]); return 1; } - else + + len = 1; + + prin (stream, "\t"); + prin (stream, "%s", op->name); + + if (op->clas == wasm_typed) { - len = 1; - - prin (stream, "\t"); - prin (stream, "%s", op->name); - - if (op->clas == wasm_typed) - { - block_type = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, FALSE); - if (error) - return -1; - len += bytes_read; - switch (block_type) - { - case BLOCK_TYPE_NONE: - prin (stream, "[]"); - break; - case BLOCK_TYPE_I32: - prin (stream, "[i]"); - break; - case BLOCK_TYPE_I64: - prin (stream, "[l]"); - break; - case BLOCK_TYPE_F32: - prin (stream, "[f]"); - break; - case BLOCK_TYPE_F64: - prin (stream, "[d]"); - break; - } - } - - switch (op->clas) - { - case wasm_special: - case wasm_eqz: - case wasm_binary: - case wasm_unary: - case wasm_conv: - case wasm_relational: - case wasm_drop: - case wasm_signature: - case wasm_call_import: - case wasm_typed: - case wasm_select: - break; - - case wasm_break_table: - target_count = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, FALSE); - if (error) - return -1; - len += bytes_read; - prin (stream, " %ld", target_count); - for (i = 0; i < target_count + 1; i++) - { - long target = 0; - target = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, FALSE); - if (error) - return -1; - len += bytes_read; - prin (stream, " %ld", target); - } - break; - - case wasm_break: - case wasm_break_if: - depth = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, FALSE); - if (error) - return -1; - len += bytes_read; - prin (stream, " %ld", depth); - break; - - case wasm_return: - break; - - case wasm_constant_i32: - case wasm_constant_i64: - constant = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, TRUE); - if (error) - return -1; - len += bytes_read; - prin (stream, " %lld", constant); - break; - - case wasm_constant_f32: - /* This appears to be the best we can do, even though we're - using host doubles for WebAssembly floats. */ - ret = read_f32 (&fconstant, pc + len, info); - if (ret < 0) - return -1; - len += ret; - prin (stream, " %.9g", fconstant); - break; - - case wasm_constant_f64: - ret = read_f64 (&fconstant, pc + len, info); - if (ret < 0) - return -1; - len += ret; - prin (stream, " %.17g", fconstant); - break; - - case wasm_call: - function_index = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, FALSE); - if (error) - return -1; - len += bytes_read; - prin (stream, " "); - private_data->section_prefix = ".space.function_index"; - (*info->print_address_func) ((bfd_vma) function_index, info); - private_data->section_prefix = NULL; - break; - - case wasm_call_indirect: - constant = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, FALSE); - if (error) - return -1; - len += bytes_read; - prin (stream, " %lld", constant); - constant = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, FALSE); - if (error) - return -1; - len += bytes_read; - prin (stream, " %lld", constant); - break; - - case wasm_get_local: - case wasm_set_local: - case wasm_tee_local: - constant = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, FALSE); - if (error) - return -1; - len += bytes_read; - prin (stream, " %lld", constant); - if (strcmp (op->name + 4, "local") == 0) - { - if (private_data->print_registers - && constant >= 0 && constant < nlocals) - prin (stream, " <%s>", locals[constant]); - } - else - { - if (private_data->print_well_known_globals - && constant >= 0 && constant < nglobals) - prin (stream, " <%s>", globals[constant]); - } - break; - - case wasm_grow_memory: - case wasm_current_memory: - constant = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, FALSE); - if (error) - return -1; - len += bytes_read; - prin (stream, " %lld", constant); - break; - - case wasm_load: - case wasm_store: - flags = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, FALSE); - if (error) - return -1; - len += bytes_read; - offset = wasm_read_leb128 - (pc + len, info, &error, &bytes_read, FALSE); - if (error) - return -1; - len += bytes_read; - prin (stream, " a=%ld %ld", flags, offset); - } + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, FALSE); + if (error) + return -1; + len += bytes_read; + switch (val) + { + case BLOCK_TYPE_NONE: + prin (stream, "[]"); + break; + case BLOCK_TYPE_I32: + prin (stream, "[i]"); + break; + case BLOCK_TYPE_I64: + prin (stream, "[l]"); + break; + case BLOCK_TYPE_F32: + prin (stream, "[f]"); + break; + case BLOCK_TYPE_F64: + prin (stream, "[d]"); + break; + default: + return -1; + } + } + + switch (op->clas) + { + case wasm_special: + case wasm_eqz: + case wasm_binary: + case wasm_unary: + case wasm_conv: + case wasm_relational: + case wasm_drop: + case wasm_signature: + case wasm_call_import: + case wasm_typed: + case wasm_select: + break; + + case wasm_break_table: + { + uint32_t target_count, i; + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, + FALSE); + target_count = val; + if (error || target_count != val || target_count == (uint32_t) -1) + return -1; + len += bytes_read; + prin (stream, " %u", target_count); + for (i = 0; i < target_count + 1; i++) + { + uint32_t target; + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, + FALSE); + target = val; + if (error || target != val) + return -1; + len += bytes_read; + prin (stream, " %u", target); + } + } + break; + + case wasm_break: + case wasm_break_if: + { + uint32_t depth; + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, + FALSE); + depth = val; + if (error || depth != val) + return -1; + len += bytes_read; + prin (stream, " %u", depth); + } + break; + + case wasm_return: + break; + + case wasm_constant_i32: + case wasm_constant_i64: + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, TRUE); + if (error) + return -1; + len += bytes_read; + prin (stream, " %" PRId64, val); + break; + + case wasm_constant_f32: + { + double fconstant; + int ret; + /* This appears to be the best we can do, even though we're + using host doubles for WebAssembly floats. */ + ret = read_f32 (&fconstant, pc + len, info); + if (ret < 0) + return -1; + len += ret; + prin (stream, " %.9g", fconstant); + } + break; + + case wasm_constant_f64: + { + double fconstant; + int ret; + ret = read_f64 (&fconstant, pc + len, info); + if (ret < 0) + return -1; + len += ret; + prin (stream, " %.17g", fconstant); + } + break; + + case wasm_call: + { + uint32_t function_index; + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, + FALSE); + function_index = val; + if (error || function_index != val) + return -1; + len += bytes_read; + prin (stream, " "); + private_data->section_prefix = ".space.function_index"; + (*info->print_address_func) ((bfd_vma) function_index, info); + private_data->section_prefix = NULL; + } + break; + + case wasm_call_indirect: + { + uint32_t type_index, xtra_index; + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, + FALSE); + type_index = val; + if (error || type_index != val) + return -1; + len += bytes_read; + prin (stream, " %u", type_index); + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, + FALSE); + xtra_index = val; + if (error || xtra_index != val) + return -1; + len += bytes_read; + prin (stream, " %u", xtra_index); + } + break; + + case wasm_get_local: + case wasm_set_local: + case wasm_tee_local: + { + uint32_t local_index; + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, + FALSE); + local_index = val; + if (error || local_index != val) + return -1; + len += bytes_read; + prin (stream, " %u", local_index); + if (strcmp (op->name + 4, "local") == 0) + { + static const char *locals[] = + { + "$dpc", "$sp1", "$r0", "$r1", "$rpc", "$pc0", + "$rp", "$fp", "$sp", + "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", + "$i0", "$i1", "$i2", "$i3", "$i4", "$i5", "$i6", "$i7", + "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", + }; + if (private_data->print_registers + && local_index < ARRAY_SIZE (locals)) + prin (stream, " <%s>", locals[local_index]); + } + else + { + static const char *globals[] = + { + "$got", "$plt", "$gpo" + }; + if (private_data->print_well_known_globals + && local_index < ARRAY_SIZE (globals)) + prin (stream, " <%s>", globals[local_index]); + } + } + break; + + case wasm_grow_memory: + case wasm_current_memory: + { + uint32_t reserved_size; + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, + FALSE); + reserved_size = val; + if (error || reserved_size != val) + return -1; + len += bytes_read; + prin (stream, " %u", reserved_size); + } + break; + + case wasm_load: + case wasm_store: + { + uint32_t flags, offset; + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, + FALSE); + flags = val; + if (error || flags != val) + return -1; + len += bytes_read; + val = wasm_read_leb128 (pc + len, info, &error, &bytes_read, + FALSE); + offset = val; + if (error || offset != val) + return -1; + len += bytes_read; + prin (stream, " a=%u %u", flags, offset); + } + break; } return len; } |