Updated APF dissembler to support WRITE/EWRITE opcodes.
Added support for WRITE opcode, which writes 1, 2, or 4 bytes from an
immediate value to the output buffer. Added support for EWRITE opcode,
which writes 1, 2, or 4 bytes from a register to the output buffer.
Bug: 293811969
Test: TH
Change-Id: Iee36500669e16e027dc8e6d3743767521ca39c66
diff --git a/disassembler.c b/disassembler.c
index 091ff9e..6db8d7d 100644
--- a/disassembler.c
+++ b/disassembler.c
@@ -55,6 +55,7 @@
[JNEBS_OPCODE] = "jnebs",
[LDDW_OPCODE] = "lddw",
[STDW_OPCODE] = "stdw",
+ [WRITE_OPCODE] = "write",
};
static int print_jump_target(uint32_t target, uint32_t program_len,
@@ -366,6 +367,20 @@
ASSERT_RET_INBOUND(ret);
offset += ret;
break;
+ case EWRITE1_EXT_OPCODE:
+ case EWRITE2_EXT_OPCODE:
+ case EWRITE4_EXT_OPCODE: {
+ ret = print_opcode("write", output_buffer,
+ output_buffer_len, offset);
+ ASSERT_RET_INBOUND(ret);
+ offset += ret;
+ ret = snprintf(output_buffer + offset,
+ output_buffer_len - offset, "r%d, %d",
+ reg_num, 1 << (imm - EWRITE1_EXT_OPCODE));
+ ASSERT_RET_INBOUND(ret);
+ offset += ret;
+ break;
+ }
default:
ret = snprintf(output_buffer + offset,
output_buffer_len - offset, "unknown_ext %u",
@@ -400,7 +415,28 @@
offset += ret;
}
break;
+ case WRITE_OPCODE: {
+ ret = PRINT_OPCODE();
+ ASSERT_RET_INBOUND(ret);
+ offset += ret;
+ uint32_t write_len = 1 << (len_field - 1);
+ if (write_len > 0) {
+ ret = snprintf(output_buffer + offset,
+ output_buffer_len - offset, "0x");
+ ASSERT_RET_INBOUND(ret);
+ offset += ret;
+ }
+ for (uint32_t i = 0; i < write_len; ++i) {
+ uint8_t byte =
+ (uint8_t) ((imm >> (write_len - 1 - i) * 8) & 0xff);
+ ret = snprintf(output_buffer + offset,
+ output_buffer_len - offset, "%02x", byte);
+ ASSERT_RET_INBOUND(ret);
+ offset += ret;
+ }
+ break;
+ }
// Unknown opcode
default:
ret = snprintf(output_buffer + offset, output_buffer_len - offset,