about summary refs log tree commit diff stats
path: root/subx/013direct_addressing.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-09-22 23:19:39 -0700
committerKartik Agaram <vc@akkartik.com>2018-09-22 23:19:39 -0700
commit7d4e351a0d1e3c4e71b58d3218b4e6b833f542f2 (patch)
tree8f8b8e62848b76ce5debf3ef89ad6f0e1c381de8 /subx/013direct_addressing.cc
parent2b36eee9b13eb16fb2e4b05d7e26f6d09f431912 (diff)
downloadmu-7d4e351a0d1e3c4e71b58d3218b4e6b833f542f2.tar.gz
4503
Include LEA (load effective address) in the SubX subset of x86 ISA.
Diffstat (limited to 'subx/013direct_addressing.cc')
-rw-r--r--subx/013direct_addressing.cc18
1 files changed, 15 insertions, 3 deletions
diff --git a/subx/013direct_addressing.cc b/subx/013direct_addressing.cc
index 0ddb1ce8..7b265a44 100644
--- a/subx/013direct_addressing.cc
+++ b/subx/013direct_addressing.cc
@@ -32,19 +32,31 @@ int32_t* effective_address(uint8_t modrm) {
   uint8_t mod = (modrm>>6);
   // ignore middle 3 'reg opcode' bits
   uint8_t rm = modrm & 0x7;
+  if (mod == 3) {
+    // mod 3 is just register direct addressing
+    trace(90, "run") << "r/m32 is " << rname(rm) << end();
+    return &Reg[rm].i;
+  }
+  return mem_addr_i32(effective_address_number(modrm));
+}
+
+uint32_t effective_address_number(uint8_t modrm) {
+  uint8_t mod = (modrm>>6);
+  // ignore middle 3 'reg opcode' bits
+  uint8_t rm = modrm & 0x7;
   uint32_t addr = 0;
   switch (mod) {
   case 3:
     // mod 3 is just register direct addressing
-    trace(90, "run") << "r/m32 is " << rname(rm) << end();
-    return &Reg[rm].i;
+    raise << "unexpected direct addressing mode\n" << end();
+    return 0;
   // End Mod Special-cases(addr)
   default:
     cerr << "unrecognized mod bits: " << NUM(mod) << '\n';
     exit(1);
   }
   //: other mods are indirect, and they'll set addr appropriately
-  return mem_addr_i32(addr);
+  return addr;
 }
 
 string rname(uint8_t r) {