Print disassembled code in apf_run.

apf_run is a great tool to debug APF programs, but it does not
currently print disassemled code. Fix this.

Before:

PC:       0 R0:       0 R1:       0
PC:       2 R0:    86dd R1:       0
PC:       7 R0:    86dd R1:       0
PC:      64 R0:    86dd R1:       0
PC:     141 R0:    86dd R1:       0

After:

      R0       R1       PC  Instruction
-------------------------------------------------
       0        0        0: ldh   r0, [12]
       2     86dd        2: jlt   r0, 0x600, drop
       7     86dd        7: jne   r0, 0x806, 64
      40     86dd       64: jne   r0, 0x800, 141
      8d     86dd      141: jeq   r0, 0x86dd, 161
...

Bug: 66928272
Test: manually compared output on a sample program
Change-Id: I1b93f70e0381d6e43d7f7d9785ab8c935baa1e4b
diff --git a/apf_disassembler.c b/apf_disassembler.c
index 818de7b..a7401f3 100644
--- a/apf_disassembler.c
+++ b/apf_disassembler.c
@@ -17,52 +17,7 @@
 #include <stdint.h>
 #include <stdio.h>
 
-#include "apf.h"
-
-// If "c" is of an unsigned type, generate a compile warning that gets promoted to an error.
-// This makes bounds checking simpler because ">= 0" can be avoided. Otherwise adding
-// superfluous ">= 0" with unsigned expressions generates compile warnings.
-#define ENFORCE_UNSIGNED(c) ((c)==(uint32_t)(c))
-
-static void print_opcode(const char* opcode) {
-  printf("%-6s", opcode);
-}
-
-// Mapping from opcode number to opcode name.
-static const char* opcode_names [] = {
-    [LDB_OPCODE] = "ldb",
-    [LDH_OPCODE] = "ldh",
-    [LDW_OPCODE] = "ldw",
-    [LDBX_OPCODE] = "ldb",
-    [LDHX_OPCODE] = "ldh",
-    [LDWX_OPCODE] = "ldw",
-    [ADD_OPCODE] = "add",
-    [MUL_OPCODE] = "mul",
-    [DIV_OPCODE] = "div",
-    [AND_OPCODE] = "and",
-    [OR_OPCODE] = "or",
-    [SH_OPCODE] = "sh",
-    [LI_OPCODE] = "li",
-    [JMP_OPCODE] = "jmp",
-    [JEQ_OPCODE] = "jeq",
-    [JNE_OPCODE] = "jne",
-    [JGT_OPCODE] = "jgt",
-    [JLT_OPCODE] = "jlt",
-    [JSET_OPCODE] = "jset",
-    [JNEBS_OPCODE] = "jnebs",
-    [LDDW_OPCODE] = "lddw",
-    [STDW_OPCODE] = "stdw",
-};
-
-static void print_jump_target(uint32_t target, uint32_t program_len) {
-    if (target == program_len) {
-        printf("pass");
-    } else if (target == program_len + 1) {
-        printf("drop");
-    } else {
-        printf("%u", target);
-    }
-}
+#include "disassembler.h"
 
 // Disassembles an APF program. A hex dump of the program is supplied on stdin.
 //
@@ -82,144 +37,6 @@
   }
 
   for (uint32_t pc = 0; pc < program_len;) {
-      printf("%8u: ", pc);
-      const uint8_t bytecode = program[pc++];
-      const uint32_t opcode = EXTRACT_OPCODE(bytecode);
-#define PRINT_OPCODE() print_opcode(opcode_names[opcode])
-      const uint32_t reg_num = EXTRACT_REGISTER(bytecode);
-      // All instructions have immediate fields, so load them now.
-      const uint32_t len_field = EXTRACT_IMM_LENGTH(bytecode);
-      uint32_t imm = 0;
-      int32_t signed_imm = 0;
-      if (len_field != 0) {
-          const uint32_t imm_len = 1 << (len_field - 1);
-          uint32_t i;
-          for (i = 0; i < imm_len && pc < program_len; i++)
-              imm = (imm << 8) | program[pc++];
-          // Sign extend imm into signed_imm.
-          signed_imm = imm << ((4 - imm_len) * 8);
-          signed_imm >>= (4 - imm_len) * 8;
-      }
-      switch (opcode) {
-          case LDB_OPCODE:
-          case LDH_OPCODE:
-          case LDW_OPCODE:
-              PRINT_OPCODE();
-              printf("r%d, [%u]", reg_num, imm);
-              break;
-          case LDBX_OPCODE:
-          case LDHX_OPCODE:
-          case LDWX_OPCODE:
-              PRINT_OPCODE();
-              printf("r%d, [%u+r1]", reg_num, imm);
-              break;
-          case JMP_OPCODE:
-              PRINT_OPCODE();
-              print_jump_target(pc + imm, program_len);
-              break;
-          case JEQ_OPCODE:
-          case JNE_OPCODE:
-          case JGT_OPCODE:
-          case JLT_OPCODE:
-          case JSET_OPCODE:
-          case JNEBS_OPCODE: {
-              PRINT_OPCODE();
-              printf("r0, ");
-              // Load second immediate field.
-              uint32_t cmp_imm = 0;
-              if (reg_num == 1) {
-                  printf("r1, ");
-              } else if (len_field == 0) {
-                  printf("0, ");
-              } else {
-                  uint32_t cmp_imm_len = 1 << (len_field - 1);
-                  uint32_t i;
-                  for (i = 0; i < cmp_imm_len && pc < program_len; i++)
-                      cmp_imm = (cmp_imm << 8) | program[pc++];
-                  printf("0x%x, ", cmp_imm);
-              }
-              if (opcode == JNEBS_OPCODE) {
-                  print_jump_target(pc + imm + cmp_imm, program_len);
-                  printf(", ");
-                  while (cmp_imm--)
-                      printf("%02x", program[pc++]);
-              } else {
-                  print_jump_target(pc + imm, program_len);
-              }
-              break;
-          }
-          case ADD_OPCODE:
-          case SH_OPCODE:
-              PRINT_OPCODE();
-              if (reg_num) {
-                  printf("r0, r1");
-              } else {
-                  printf("r0, %d", signed_imm);
-              }
-              break;
-          case MUL_OPCODE:
-          case DIV_OPCODE:
-          case AND_OPCODE:
-          case OR_OPCODE:
-              PRINT_OPCODE();
-              if (reg_num) {
-                  printf("r0, r1");
-              } else {
-                  printf("r0, %u", imm);
-              }
-              break;
-          case LI_OPCODE:
-              PRINT_OPCODE();
-              printf("r%d, %d", reg_num, signed_imm);
-              break;
-          case EXT_OPCODE:
-              if (
-// If LDM_EXT_OPCODE is 0 and imm is compared with it, a compiler error will result,
-// instead just enforce that imm is unsigned (so it's always greater or equal to 0).
-#if LDM_EXT_OPCODE == 0
-                  ENFORCE_UNSIGNED(imm) &&
-#else
-                  imm >= LDM_EXT_OPCODE &&
-#endif
-                  imm < (LDM_EXT_OPCODE + MEMORY_ITEMS)) {
-                  print_opcode("ldm");
-                  printf("r%d, m[%u]", reg_num, imm - LDM_EXT_OPCODE);
-              } else if (imm >= STM_EXT_OPCODE && imm < (STM_EXT_OPCODE + MEMORY_ITEMS)) {
-                  print_opcode("stm");
-                  printf("r%d, m[%u]", reg_num, imm - STM_EXT_OPCODE);
-              } else switch (imm) {
-                  case NOT_EXT_OPCODE:
-                      print_opcode("not");
-                      printf("r%d", reg_num);
-                      break;
-                  case NEG_EXT_OPCODE:
-                      print_opcode("neg");
-                      printf("r%d", reg_num);
-                      break;
-                  case SWAP_EXT_OPCODE:
-                      print_opcode("swap");
-                      break;
-                  case MOV_EXT_OPCODE:
-                      print_opcode("mov");
-                      printf("r%d, r%d", reg_num, reg_num ^ 1);
-                      break;
-                  default:
-                      printf("unknown_ext %u", imm);
-                      break;
-              }
-              break;
-          case LDDW_OPCODE:
-          case STDW_OPCODE:
-              PRINT_OPCODE();
-              printf("r%u, [%d+r%u]", reg_num, signed_imm, reg_num ^ 1);
-              break;
-
-          // Unknown opcode
-          default:
-              printf("unknown %u", opcode);
-              break;
-      }
-      printf("\n");
+      pc = apf_disassemble(program, program_len, pc);
   }
-  return 0;
 }