From f676051522eb5fe6a59b3c295f49cb8c79f898a6 Mon Sep 17 00:00:00 2001
From: Recolic Keghart <root@recolic.net>
Date: Fri, 27 Dec 2019 00:18:05 -0800
Subject: [PATCH] >  Manual commit:  Finished DHelper/EHelper naming
 reconstruct. U201614531 recolic Linux RECOLICMPC 4.19.84-1-MANJARO #1 SMP
 PREEMPT Wed Nov 13 00:07:37 UTC 2019 x86_64 GNU/Linux  00:18:05 up 21 days, 
 1:46,  1 user,  load average: 0.45, 0.49, 0.43
 87ec359498ee755c2b1a53bde2e7ccb52afc8541

---
 nemu/include/cpu/exec.h       |   2 +-
 nemu/src/cpu/decode/decode.cc | 621 +++++++++++++++++-----------------
 nemu/src/cpu/exec/all-instr.h |  13 +-
 nemu/src/cpu/exec/arith.cc    | 512 ++++++++++++++--------------
 nemu/src/cpu/exec/control.cc  | 128 +++----
 nemu/src/cpu/exec/data-mov.cc | 180 +++++-----
 nemu/src/cpu/exec/exec.cc     |  35 +-
 nemu/src/cpu/exec/logic.cc    | 170 +++++-----
 nemu/src/cpu/exec/special.cc  |  88 ++---
 nemu/src/cpu/exec/system.cc   | 116 +++----
 10 files changed, 940 insertions(+), 925 deletions(-)

diff --git a/nemu/include/cpu/exec.h b/nemu/include/cpu/exec.h
index 363039e..7766871 100644
--- a/nemu/include/cpu/exec.h
+++ b/nemu/include/cpu/exec.h
@@ -3,7 +3,7 @@
 
 #include "nemu.h"
 
-#define make_EHelper(name) void name (vaddr_t *eip)
+#define make_EHelper(name) void name(vaddr_t *eip)
 typedef void (*EHelper) (vaddr_t *);
 
 #include "cpu/decode.h"
diff --git a/nemu/src/cpu/decode/decode.cc b/nemu/src/cpu/decode/decode.cc
index 73aab67..94c08ab 100644
--- a/nemu/src/cpu/decode/decode.cc
+++ b/nemu/src/cpu/decode/decode.cc
@@ -9,322 +9,327 @@ void decoding_set_jmp(bool is_jmp) {
   decoding.is_jmp = is_jmp;
 }
 
-#define make_DopHelper_funcname(name) concat(decode_op_, name)
-#define make_DopHelper(name) void make_DopHelper_funcname(name) (vaddr_t *eip, Operand *op, bool load_val)
-
-/* Refer to Appendix A in i386 manual for the explanations of these abbreviations */
-
-/* Ib, Iv */
-static inline make_DopHelper(I) {
-  /* eip here is pointing to the immediate */
-  op->type = OP_TYPE_IMM;
-  op->imm = instr_fetch(eip, op->width);
-  rtl_li(&op->val, op->imm);
-
-#ifdef DEBUG
-  snprintf(op->str, OP_STR_SIZE, "$0x%x", op->imm);
-#endif
-}
-
-/* I386 manual does not contain this abbreviation, but it is different from
- * the one above from the view of implementation. So we use another helper
- * function to decode it.
- */
-/* sign immediate */
-static inline make_DopHelper(SI) {
-  assert(op->width == 1 || op->width == 4);
-
-  op->type = OP_TYPE_IMM;
-
-  /* TODO: Use instr_fetch() to read `op->width' bytes of memory
-   * pointed by `eip'. Interpret the result as a signed immediate,
-   * and assign it to op->simm.
-   *
-   op->simm = ???
+#define make_DopHelper_funcname(name) DopHelperImpl::name
+#define make_DopHelper(name) void name (vaddr_t *eip, Operand *op, bool load_val)
+
+namespace DopHelperImpl {
+  /* Refer to Appendix A in i386 manual for the explanations of these abbreviations */
+  
+  /* Ib, Iv */
+  static inline make_DopHelper(I) {
+    /* eip here is pointing to the immediate */
+    op->type = OP_TYPE_IMM;
+    op->imm = instr_fetch(eip, op->width);
+    rtl_li(&op->val, op->imm);
+  
+  #ifdef DEBUG
+    snprintf(op->str, OP_STR_SIZE, "$0x%x", op->imm);
+  #endif
+  }
+  
+  /* I386 manual does not contain this abbreviation, but it is different from
+   * the one above from the view of implementation. So we use another helper
+   * function to decode it.
    */
-  op->simm = instr_fetch(eip, op->width);
-
-  rtl_li(&op->val, op->simm);
-
-#ifdef DEBUG
-  snprintf(op->str, OP_STR_SIZE, "$0x%x", op->simm);
-#endif
-}
-
-/* I386 manual does not contain this abbreviation.
- * It is convenient to merge them into a single helper function.
- */
-/* AL/eAX */
-static inline make_DopHelper(a) {
-  op->type = OP_TYPE_REG;
-  op->reg = R_EAX;
-  if (load_val) {
-    rtl_lr(&op->val, R_EAX, op->width);
+  /* sign immediate */
+  static inline make_DopHelper(SI) {
+    assert(op->width == 1 || op->width == 4);
+  
+    op->type = OP_TYPE_IMM;
+  
+    /* TODO: Use instr_fetch() to read `op->width' bytes of memory
+     * pointed by `eip'. Interpret the result as a signed immediate,
+     * and assign it to op->simm.
+     *
+     op->simm = ???
+     */
+    op->simm = instr_fetch(eip, op->width);
+  
+    rtl_li(&op->val, op->simm);
+  
+  #ifdef DEBUG
+    snprintf(op->str, OP_STR_SIZE, "$0x%x", op->simm);
+  #endif
   }
-
-#ifdef DEBUG
-  snprintf(op->str, OP_STR_SIZE, "%%%s", reg_name(R_EAX, op->width));
-#endif
-}
-
-/* This helper function is use to decode register encoded in the opcode. */
-/* XX: AL, AH, BL, BH, CL, CH, DL, DH
- * eXX: eAX, eCX, eDX, eBX, eSP, eBP, eSI, eDI
- */
-static inline make_DopHelper(r) {
-  op->type = OP_TYPE_REG;
-  op->reg = decoding.opcode & 0x7;
-  if (load_val) {
-    rtl_lr(&op->val, op->reg, op->width);
+  
+  /* I386 manual does not contain this abbreviation.
+   * It is convenient to merge them into a single helper function.
+   */
+  /* AL/eAX */
+  static inline make_DopHelper(a) {
+    op->type = OP_TYPE_REG;
+    op->reg = R_EAX;
+    if (load_val) {
+      rtl_lr(&op->val, R_EAX, op->width);
+    }
+  
+  #ifdef DEBUG
+    snprintf(op->str, OP_STR_SIZE, "%%%s", reg_name(R_EAX, op->width));
+  #endif
   }
-
-#ifdef DEBUG
-  snprintf(op->str, OP_STR_SIZE, "%%%s", reg_name(op->reg, op->width));
-#endif
-}
-
-/* I386 manual does not contain this abbreviation.
- * We decode everything of modR/M byte by one time.
- */
-/* Eb, Ew, Ev
- * Gb, Gv
- * Cd,
- * M
- * Rd
- * Sw
- */
-static inline void make_DopHelper_funcname(rm)(vaddr_t *eip, Operand *rm, bool load_rm_val, Operand *reg, bool load_reg_val) {
-  read_ModR_M(eip, rm, load_rm_val, reg, load_reg_val);
-}
-
-/* Ob, Ov */
-static inline make_DopHelper(O) {
-  op->type = OP_TYPE_MEM;
-  rtl_li(&op->addr, instr_fetch(eip, 4));
-  if (load_val) {
-    rtl_lm(&op->val, &op->addr, op->width);
+  
+  /* This helper function is use to decode register encoded in the opcode. */
+  /* XX: AL, AH, BL, BH, CL, CH, DL, DH
+   * eXX: eAX, eCX, eDX, eBX, eSP, eBP, eSI, eDI
+   */
+  static inline make_DopHelper(r) {
+    op->type = OP_TYPE_REG;
+    op->reg = decoding.opcode & 0x7;
+    if (load_val) {
+      rtl_lr(&op->val, op->reg, op->width);
+    }
+  
+  #ifdef DEBUG
+    snprintf(op->str, OP_STR_SIZE, "%%%s", reg_name(op->reg, op->width));
+  #endif
   }
-
-#ifdef DEBUG
-  snprintf(op->str, OP_STR_SIZE, "0x%x", op->addr);
-#endif
-}
-
-/* Eb <- Gb
- * Ev <- Gv
- */
-make_DHelper(G2E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, true, id_src, true);
-}
-
-make_DHelper(mov_G2E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, false, id_src, true);
-}
-
-/* Gb <- Eb
- * Gv <- Ev
- */
-make_DHelper(E2G) {
-  make_DopHelper_funcname(rm)(eip, id_src, true, id_dest, true);
-}
-
-make_DHelper(mov_E2G) {
-  make_DopHelper_funcname(rm)(eip, id_src, true, id_dest, false);
-}
-
-make_DHelper(lea_M2G) {
-  make_DopHelper_funcname(rm)(eip, id_src, false, id_dest, false);
-}
-
-/* AL <- Ib
- * eAX <- Iv
- */
-make_DHelper(I2a) {
-  make_DopHelper_funcname(a)(eip, id_dest, true);
-  make_DopHelper_funcname(I)(eip, id_src, true);
-}
-
-/* Gv <- EvIb
- * Gv <- EvIv
- * use for imul */
-make_DHelper(I_E2G) {
-  make_DopHelper_funcname(rm)(eip, id_src2, true, id_dest, false);
-  make_DopHelper_funcname(I)(eip, id_src, true);
-}
-
-/* Eb <- Ib
- * Ev <- Iv
- */
-make_DHelper(I2E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
-  make_DopHelper_funcname(I)(eip, id_src, true);
-}
-
-make_DHelper(mov_I2E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, false, NULL, false);
-  make_DopHelper_funcname(I)(eip, id_src, true);
-}
-
-/* XX <- Ib
- * eXX <- Iv
- */
-make_DHelper(I2r) {
-  make_DopHelper_funcname(r)(eip, id_dest, true);
-  make_DopHelper_funcname(I)(eip, id_src, true);
-}
-
-make_DHelper(mov_I2r) {
-  make_DopHelper_funcname(r)(eip, id_dest, false);
-  make_DopHelper_funcname(I)(eip, id_src, true);
-}
-
-/* used by unary operations */
-make_DHelper(I) {
-  make_DopHelper_funcname(I)(eip, id_dest, true);
-}
-
-make_DHelper(r) {
-  make_DopHelper_funcname(r)(eip, id_dest, true);
-}
-
-make_DHelper(E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
-}
-
-make_DHelper(setcc_E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, false, NULL, false);
-}
-
-make_DHelper(gp7_E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, false, NULL, false);
-}
-
-/* used by test in group3 */
-make_DHelper(test_I) {
-  make_DopHelper_funcname(I)(eip, id_src, true);
-}
-
-make_DHelper(SI2E) {
-  assert(id_dest->width == 2 || id_dest->width == 4);
-  make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
-  id_src->width = 1;
-  make_DopHelper_funcname(SI)(eip, id_src, true);
-  if (id_dest->width == 2) {
-    id_src->val &= 0xffff;
+  
+  /* I386 manual does not contain this abbreviation.
+   * We decode everything of modR/M byte by one time.
+   */
+  /* Eb, Ew, Ev
+   * Gb, Gv
+   * Cd,
+   * M
+   * Rd
+   * Sw
+   */
+  static inline void rm(vaddr_t *eip, Operand *rm, bool load_rm_val, Operand *reg, bool load_reg_val) {
+    read_ModR_M(eip, rm, load_rm_val, reg, load_reg_val);
   }
-}
-
-make_DHelper(SI_E2G) {
-  assert(id_dest->width == 2 || id_dest->width == 4);
-  make_DopHelper_funcname(rm)(eip, id_src2, true, id_dest, false);
-  id_src->width = 1;
-  make_DopHelper_funcname(SI)(eip, id_src, true);
-  if (id_dest->width == 2) {
-    id_src->val &= 0xffff;
+  
+  /* Ob, Ov */
+  static inline make_DopHelper(O) {
+    op->type = OP_TYPE_MEM;
+    rtl_li(&op->addr, instr_fetch(eip, 4));
+    if (load_val) {
+      rtl_lm(&op->val, &op->addr, op->width);
+    }
+  
+  #ifdef DEBUG
+    snprintf(op->str, OP_STR_SIZE, "0x%x", op->addr);
+  #endif
   }
-}
+} // end namespace DopHelperImpl
 
-make_DHelper(gp2_1_E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
-  id_src->type = OP_TYPE_IMM;
-  id_src->imm = 1;
-  rtl_li(&id_src->val, 1);
-#ifdef DEBUG
-  sprintf(id_src->str, "$1");
-#endif
-}
-
-make_DHelper(gp2_cl2E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
-  id_src->type = OP_TYPE_REG;
-  id_src->reg = R_CL;
-  rtl_lr(&id_src->val, R_CL, 1);
-#ifdef DEBUG
-  sprintf(id_src->str, "%%cl");
-#endif
-}
-
-make_DHelper(gp2_Ib2E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
-  id_src->width = 1;
-  make_DopHelper_funcname(I)(eip, id_src, true);
-}
-
-/* Ev <- GvIb
- * use for shld/shrd */
-make_DHelper(Ib_G2E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, true, id_src2, true);
-  id_src->width = 1;
-  make_DopHelper_funcname(I)(eip, id_src, true);
-}
-
-/* Ev <- GvCL
- * use for shld/shrd */
-make_DHelper(cl_G2E) {
-  make_DopHelper_funcname(rm)(eip, id_dest, true, id_src2, true);
-  id_src->type = OP_TYPE_REG;
-  id_src->reg = R_CL;
-  rtl_lr(&id_src->val, R_CL, 1);
-#ifdef DEBUG
-  sprintf(id_src->str, "%%cl");
-#endif
-}
-
-make_DHelper(O2a) {
-  make_DopHelper_funcname(O)(eip, id_src, true);
-  make_DopHelper_funcname(a)(eip, id_dest, false);
-}
-
-make_DHelper(a2O) {
-  make_DopHelper_funcname(a)(eip, id_src, true);
-  make_DopHelper_funcname(O)(eip, id_dest, false);
-}
-
-make_DHelper(J) {
-  make_DopHelper_funcname(SI)(eip, id_dest, false);
-  rlib::println("debug: J decoder: id_dest=", *id_dest);
-  rtl_sext(&id_dest->imm, &id_dest->imm, id_dest->width);
-  // the target address can be computed in the decode stage
-  decoding.jmp_eip = id_dest->simm + *eip;
-}
-
-make_DHelper(push_SI) {
-  make_DopHelper_funcname(SI)(eip, id_dest, true);
-}
-
-make_DHelper(in_I2a) {
-  id_src->width = 1;
-  make_DopHelper_funcname(I)(eip, id_src, true);
-  make_DopHelper_funcname(a)(eip, id_dest, false);
-}
-
-make_DHelper(in_dx2a) {
-  id_src->type = OP_TYPE_REG;
-  id_src->reg = R_DX;
-  rtl_lr(&id_src->val, R_DX, 2);
-#ifdef DEBUG
-  sprintf(id_src->str, "(%%dx)");
-#endif
-
-  make_DopHelper_funcname(a)(eip, id_dest, false);
-}
-
-make_DHelper(out_a2I) {
-  make_DopHelper_funcname(a)(eip, id_src, true);
-  id_dest->width = 1;
-  make_DopHelper_funcname(I)(eip, id_dest, true);
-}
+namespace DHelperImpl {
 
-make_DHelper(out_a2dx) {
-  make_DopHelper_funcname(a)(eip, id_src, true);
-
-  id_dest->type = OP_TYPE_REG;
-  id_dest->reg = R_DX;
-  rtl_lr(&id_dest->val, R_DX, 2);
-#ifdef DEBUG
-  sprintf(id_dest->str, "(%%dx)");
-#endif
-}
+  /* Eb <- Gb
+   * Ev <- Gv
+   */
+  make_DHelper(G2E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, true, id_src, true);
+  }
+  
+  make_DHelper(mov_G2E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, false, id_src, true);
+  }
+  
+  /* Gb <- Eb
+   * Gv <- Ev
+   */
+  make_DHelper(E2G) {
+    make_DopHelper_funcname(rm)(eip, id_src, true, id_dest, true);
+  }
+  
+  make_DHelper(mov_E2G) {
+    make_DopHelper_funcname(rm)(eip, id_src, true, id_dest, false);
+  }
+  
+  make_DHelper(lea_M2G) {
+    make_DopHelper_funcname(rm)(eip, id_src, false, id_dest, false);
+  }
+  
+  /* AL <- Ib
+   * eAX <- Iv
+   */
+  make_DHelper(I2a) {
+    make_DopHelper_funcname(a)(eip, id_dest, true);
+    make_DopHelper_funcname(I)(eip, id_src, true);
+  }
+  
+  /* Gv <- EvIb
+   * Gv <- EvIv
+   * use for imul */
+  make_DHelper(I_E2G) {
+    make_DopHelper_funcname(rm)(eip, id_src2, true, id_dest, false);
+    make_DopHelper_funcname(I)(eip, id_src, true);
+  }
+  
+  /* Eb <- Ib
+   * Ev <- Iv
+   */
+  make_DHelper(I2E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
+    make_DopHelper_funcname(I)(eip, id_src, true);
+  }
+  
+  make_DHelper(mov_I2E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, false, NULL, false);
+    make_DopHelper_funcname(I)(eip, id_src, true);
+  }
+  
+  /* XX <- Ib
+   * eXX <- Iv
+   */
+  make_DHelper(I2r) {
+    make_DopHelper_funcname(r)(eip, id_dest, true);
+    make_DopHelper_funcname(I)(eip, id_src, true);
+  }
+  
+  make_DHelper(mov_I2r) {
+    make_DopHelper_funcname(r)(eip, id_dest, false);
+    make_DopHelper_funcname(I)(eip, id_src, true);
+  }
+  
+  /* used by unary operations */
+  make_DHelper(I) {
+    make_DopHelper_funcname(I)(eip, id_dest, true);
+  }
+  
+  make_DHelper(r) {
+    make_DopHelper_funcname(r)(eip, id_dest, true);
+  }
+  
+  make_DHelper(E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
+  }
+  
+  make_DHelper(setcc_E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, false, NULL, false);
+  }
+  
+  make_DHelper(gp7_E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, false, NULL, false);
+  }
+  
+  /* used by test in group3 */
+  make_DHelper(test_I) {
+    make_DopHelper_funcname(I)(eip, id_src, true);
+  }
+  
+  make_DHelper(SI2E) {
+    assert(id_dest->width == 2 || id_dest->width == 4);
+    make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
+    id_src->width = 1;
+    make_DopHelper_funcname(SI)(eip, id_src, true);
+    if (id_dest->width == 2) {
+      id_src->val &= 0xffff;
+    }
+  }
+  
+  make_DHelper(SI_E2G) {
+    assert(id_dest->width == 2 || id_dest->width == 4);
+    make_DopHelper_funcname(rm)(eip, id_src2, true, id_dest, false);
+    id_src->width = 1;
+    make_DopHelper_funcname(SI)(eip, id_src, true);
+    if (id_dest->width == 2) {
+      id_src->val &= 0xffff;
+    }
+  }
+  
+  make_DHelper(gp2_1_E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
+    id_src->type = OP_TYPE_IMM;
+    id_src->imm = 1;
+    rtl_li(&id_src->val, 1);
+  #ifdef DEBUG
+    sprintf(id_src->str, "$1");
+  #endif
+  }
+  
+  make_DHelper(gp2_cl2E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
+    id_src->type = OP_TYPE_REG;
+    id_src->reg = R_CL;
+    rtl_lr(&id_src->val, R_CL, 1);
+  #ifdef DEBUG
+    sprintf(id_src->str, "%%cl");
+  #endif
+  }
+  
+  make_DHelper(gp2_Ib2E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, true, NULL, false);
+    id_src->width = 1;
+    make_DopHelper_funcname(I)(eip, id_src, true);
+  }
+  
+  /* Ev <- GvIb
+   * use for shld/shrd */
+  make_DHelper(Ib_G2E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, true, id_src2, true);
+    id_src->width = 1;
+    make_DopHelper_funcname(I)(eip, id_src, true);
+  }
+  
+  /* Ev <- GvCL
+   * use for shld/shrd */
+  make_DHelper(cl_G2E) {
+    make_DopHelper_funcname(rm)(eip, id_dest, true, id_src2, true);
+    id_src->type = OP_TYPE_REG;
+    id_src->reg = R_CL;
+    rtl_lr(&id_src->val, R_CL, 1);
+  #ifdef DEBUG
+    sprintf(id_src->str, "%%cl");
+  #endif
+  }
+  
+  make_DHelper(O2a) {
+    make_DopHelper_funcname(O)(eip, id_src, true);
+    make_DopHelper_funcname(a)(eip, id_dest, false);
+  }
+  
+  make_DHelper(a2O) {
+    make_DopHelper_funcname(a)(eip, id_src, true);
+    make_DopHelper_funcname(O)(eip, id_dest, false);
+  }
+  
+  make_DHelper(J) {
+    make_DopHelper_funcname(SI)(eip, id_dest, false);
+    rlib::println("debug: J decoder: id_dest=", *id_dest);
+    rtl_sext(&id_dest->imm, &id_dest->imm, id_dest->width);
+    // the target address can be computed in the decode stage
+    decoding.jmp_eip = id_dest->simm + *eip;
+  }
+  
+  make_DHelper(push_SI) {
+    make_DopHelper_funcname(SI)(eip, id_dest, true);
+  }
+  
+  make_DHelper(in_I2a) {
+    id_src->width = 1;
+    make_DopHelper_funcname(I)(eip, id_src, true);
+    make_DopHelper_funcname(a)(eip, id_dest, false);
+  }
+  
+  make_DHelper(in_dx2a) {
+    id_src->type = OP_TYPE_REG;
+    id_src->reg = R_DX;
+    rtl_lr(&id_src->val, R_DX, 2);
+  #ifdef DEBUG
+    sprintf(id_src->str, "(%%dx)");
+  #endif
+  
+    make_DopHelper_funcname(a)(eip, id_dest, false);
+  }
+  
+  make_DHelper(out_a2I) {
+    make_DopHelper_funcname(a)(eip, id_src, true);
+    id_dest->width = 1;
+    make_DopHelper_funcname(I)(eip, id_dest, true);
+  }
+  
+  make_DHelper(out_a2dx) {
+    make_DopHelper_funcname(a)(eip, id_src, true);
+  
+    id_dest->type = OP_TYPE_REG;
+    id_dest->reg = R_DX;
+    rtl_lr(&id_dest->val, R_DX, 2);
+  #ifdef DEBUG
+    sprintf(id_dest->str, "(%%dx)");
+  #endif
+  }
+} // end namespace DHelperIMpl
 
 void operand_write(Operand *op, rtlreg_t* src) {
   if (op->type == OP_TYPE_REG) { rtl_sr(op->reg, src, op->width); }
diff --git a/nemu/src/cpu/exec/all-instr.h b/nemu/src/cpu/exec/all-instr.h
index 31cb2fa..9f47be6 100644
--- a/nemu/src/cpu/exec/all-instr.h
+++ b/nemu/src/cpu/exec/all-instr.h
@@ -2,8 +2,6 @@
 
 namespace EHelperImpl {
 
-make_EHelper(_2byte_esc);
-
 make_EHelper(mov);
 make_EHelper(push);
 make_EHelper(pop);
@@ -31,12 +29,12 @@ make_EHelper(imul3);
 make_EHelper(div);
 make_EHelper(idiv);
 
-make_EHelper(xor);
+make_EHelper(xor_);
 make_EHelper(test);
-make_EHelper(and);
-make_EHelper(or);
+make_EHelper(and_);
+make_EHelper(or_);
 make_EHelper(setcc);
-make_EHelper(not);
+make_EHelper(not_);
 make_EHelper(sar);
 make_EHelper(shr);
 make_EHelper(shl);
@@ -51,6 +49,7 @@ make_EHelper(jcc);
 
 make_EHelper(in);
 make_EHelper(out);
+make_EHelper(int_);
 
 make_EHelper(nop);
 
@@ -59,4 +58,4 @@ make_EHelper(operand_size);
 make_EHelper(inv);
 make_EHelper(nemu_trap);
 
-}
\ No newline at end of file
+}
diff --git a/nemu/src/cpu/exec/arith.cc b/nemu/src/cpu/exec/arith.cc
index 409c19f..8f6c9cb 100644
--- a/nemu/src/cpu/exec/arith.cc
+++ b/nemu/src/cpu/exec/arith.cc
@@ -3,264 +3,264 @@
 #include <util/util.h>
 
 namespace EHelperImpl {
-make_EHelper(add) {
-	rtl_sext(&t1, &id_dest->val, id_dest->width);
-	rtl_sext(&t2, &id_src->val, id_src->width);
-
-	rtl_add(&t0, &t1, &t2);
-	t3 = (t0 < t1);
-	rtl_set_CF(&t3);
-	t3 = ((((int32_t)(t1) >= 0) ^ (((int32_t)(t2) >= 0 ))) && (((int32_t)(t0) < 0) ^ (((int32_t)(t2) >= 0 )) ));
-	rtl_set_OF(&t3);
-	rtl_update_ZFSF(&t0, 4);
-	operand_write(id_dest, &t0);
-
-  print_asm_template2(add);
-}
-
-make_EHelper(sub) {
-	rtl_sext(&t1, &id_dest->val, id_dest->width);
-	rtl_sext(&t2, &id_src->val, id_src->width);
-
-	rtl_sub(&t0, &t1, &t2);
-	t3 = (t0 > t1);
-	rtl_set_CF(&t3);
-	t3 = ((((int32_t)(t1) < 0) == (((int32_t)(t2) >> 31) == 0)) && (((int32_t)(t0) < 0) != ((int32_t)(t1) < 0)));
-	rtl_set_OF(&t3);
-	rtl_update_ZFSF(&t0, 4);
-	operand_write(id_dest, &t0);
-
-  print_asm_template2(sub);
-}
-
-
-
-make_EHelper(cmp) {
-	rtl_sext(&t1, &id_dest->val, id_dest->width);
-	rtl_sext(&t2, &id_src->val, id_src->width);
-
-	rtl_sub(&t0, &t1, &t2);
-	t3 = (t0 > t1);
-	rtl_set_CF(&t3);
-	t3 = ((((int32_t)(t1) < 0) == (((int32_t)(t2) >> 31) == 0)) && (((int32_t)(t0) < 0) != ((int32_t)(t1) < 0)));
-	rtl_set_OF(&t3);
-	rtl_update_ZFSF(&t0, 4);
-
-  print_asm_template2(cmp);
-}
-
-make_EHelper(inc) {
-	rtl_addi(&t2, &id_dest->val, 1);
-	operand_write(id_dest, &t2);
-	rtl_update_ZFSF(&t2, id_dest->width);
-	rtl_xor(&t0, &id_dest->val, &id_src->val);
-	rtl_not(&t0, &t0);
-	rtl_xor(&t1, &id_dest->val, &t2);
-	rtl_and(&t0, &t0, &t1);
-	rtl_msb(&t0, &t0, id_dest->width);
-	rtl_set_OF(&t0);
-
-  print_asm_template1(inc);
-}
-
-make_EHelper(dec) {
-  rtl_subi(&t2, &id_dest->val, 1);
-	operand_write(id_dest, &t2);
-
-	rtl_update_ZFSF(&t2, id_dest->width);
-
-	rtl_xor(&t0, &id_dest->val, &id_src->val);
-	rtl_xor(&t1, &id_dest->val, &t2);
-	rtl_and(&t0, &t0, &t1);
-	rtl_msb(&t0, &t0, id_dest->width);
-	rtl_set_OF(&t0);
-
-  print_asm_template1(dec);
-}
-
-make_EHelper(neg) {
-  TODO();
-
-  print_asm_template1(neg);
-}
-
-make_EHelper(adc) {
-  rtl_add(&t2, &id_dest->val, &id_src->val);
-  rtl_setrelop(RELOP_LTU, &t3, &t2, &id_dest->val);
-  rtl_get_CF(&t1);
-  rtl_add(&t2, &t2, &t1);
-  operand_write(id_dest, &t2);
-
-  rtl_update_ZFSF(&t2, id_dest->width);
-
-  rtl_setrelop(RELOP_LTU, &t0, &t2, &id_dest->val);
-  rtl_or(&t0, &t3, &t0);
-  rtl_set_CF(&t0);
-
-  rtl_xor(&t0, &id_dest->val, &id_src->val);
-  rtl_not(&t0, &t0);
-  rtl_xor(&t1, &id_dest->val, &t2);
-  rtl_and(&t0, &t0, &t1);
-  rtl_msb(&t0, &t0, id_dest->width);
-  rtl_set_OF(&t0);
-
-  print_asm_template2(adc);
-}
-
-make_EHelper(sbb) {
-  rtl_sub(&t2, &id_dest->val, &id_src->val);
-  rtl_setrelop(RELOP_LTU, &t3, &id_dest->val, &t2);
-  rtl_get_CF(&t1);
-  rtl_sub(&t2, &t2, &t1);
-  operand_write(id_dest, &t2);
-
-  rtl_update_ZFSF(&t2, id_dest->width);
-
-  rtl_setrelop(RELOP_LTU, &t0, &id_dest->val, &t2);
-  rtl_or(&t0, &t3, &t0);
-  rtl_set_CF(&t0);
-
-  rtl_xor(&t0, &id_dest->val, &id_src->val);
-  rtl_xor(&t1, &id_dest->val, &t2);
-  rtl_and(&t0, &t0, &t1);
-  rtl_msb(&t0, &t0, id_dest->width);
-  rtl_set_OF(&t0);
-
-  print_asm_template2(sbb);
-}
-
-make_EHelper(mul) {
-  rtl_lr(&t0, R_EAX, id_dest->width);
-  rtl_mul_lo(&t1, &id_dest->val, &t0);
-
-  switch (id_dest->width) {
-    case 1:
-      rtl_sr(R_AX, &t1, 2);
-      break;
-    case 2:
-      rtl_sr(R_AX, &t1, 2);
-      rtl_shri(&t1, &t1, 16);
-      rtl_sr(R_DX, &t1, 2);
-      break;
-    case 4:
-      rtl_mul_hi(&t2, &id_dest->val, &t0);
-      rtl_sr(R_EDX, &t2, 4);
-      rtl_sr(R_EAX, &t1, 4);
-      break;
-    default: assert(0);
+  make_EHelper(add) {
+  	rtl_sext(&t1, &id_dest->val, id_dest->width);
+  	rtl_sext(&t2, &id_src->val, id_src->width);
+  
+  	rtl_add(&t0, &t1, &t2);
+  	t3 = (t0 < t1);
+  	rtl_set_CF(&t3);
+  	t3 = ((((int32_t)(t1) >= 0) ^ (((int32_t)(t2) >= 0 ))) && (((int32_t)(t0) < 0) ^ (((int32_t)(t2) >= 0 )) ));
+  	rtl_set_OF(&t3);
+  	rtl_update_ZFSF(&t0, 4);
+  	operand_write(id_dest, &t0);
+  
+    print_asm_template2(add);
   }
-
-  print_asm_template1(mul);
-}
-
-// imul with one operand
-make_EHelper(imul1) {
-  rtl_lr(&t0, R_EAX, id_dest->width);
-  rtl_imul_lo(&t1, &id_dest->val, &t0);
-
-  switch (id_dest->width) {
-    case 1:
-      rtl_sr(R_AX, &t1, 2);
-      break;
-    case 2:
-      rtl_sr(R_AX, &t1, 2);
-      rtl_shri(&t1, &t1, 16);
-      rtl_sr(R_DX, &t1, 2);
-      break;
-    case 4:
-      rtl_imul_hi(&t2, &id_dest->val, &t0);
-      rtl_sr(R_EDX, &t2, 4);
-      rtl_sr(R_EAX, &t1, 4);
-      break;
-    default: assert(0);
+  
+  make_EHelper(sub) {
+  	rtl_sext(&t1, &id_dest->val, id_dest->width);
+  	rtl_sext(&t2, &id_src->val, id_src->width);
+  
+  	rtl_sub(&t0, &t1, &t2);
+  	t3 = (t0 > t1);
+  	rtl_set_CF(&t3);
+  	t3 = ((((int32_t)(t1) < 0) == (((int32_t)(t2) >> 31) == 0)) && (((int32_t)(t0) < 0) != ((int32_t)(t1) < 0)));
+  	rtl_set_OF(&t3);
+  	rtl_update_ZFSF(&t0, 4);
+  	operand_write(id_dest, &t0);
+  
+    print_asm_template2(sub);
   }
-
-  print_asm_template1(imul);
-}
-
-// imul with two operands
-make_EHelper(imul2) {
-  rtl_sext(&t0, &id_src->val, id_src->width);
-  rtl_sext(&t1, &id_dest->val, id_dest->width);
-
-  rtl_imul_lo(&t2, &t1, &t0);
-  operand_write(id_dest, &t2);
-
-  print_asm_template2(imul);
-}
-
-// imul with three operands
-make_EHelper(imul3) {
-  rtl_sext(&t0, &id_src->val, id_src->width);
-  rtl_sext(&t1, &id_src2->val, id_src->width);
-  rtl_sext(&id_dest->val, &id_dest->val, id_dest->width);
-
-  rtl_imul_lo(&t2, &t1, &t0);
-  operand_write(id_dest, &t2);
-
-  print_asm_template3(imul);
-}
-
-make_EHelper(div) {
-  switch (id_dest->width) {
-    case 1:
-      rtl_lr(&t0, R_AX, 2);
-      rtl_div_q(&t2, &t0, &id_dest->val);
-      rtl_div_r(&t3, &t0, &id_dest->val);
-      rtl_sr(R_AL, &t2, 1);
-      rtl_sr(R_AH, &t3, 1);
-      break;
-    case 2:
-      rtl_lr(&t0, R_AX, 2);
-      rtl_lr(&t1, R_DX, 2);
-      rtl_shli(&t1, &t1, 16);
-      rtl_or(&t0, &t0, &t1);
-      rtl_div_q(&t2, &t0, &id_dest->val);
-      rtl_div_r(&t3, &t0, &id_dest->val);
-      rtl_sr(R_AX, &t2, 2);
-      rtl_sr(R_DX, &t3, 2);
-      break;
-    case 4:
-      rtl_lr(&t0, R_EAX, 4);
-      rtl_lr(&t1, R_EDX, 4);
-      rtl_div64_q(&cpu.eax, &t1, &t0, &id_dest->val);
-      rtl_div64_r(&cpu.edx, &t1, &t0, &id_dest->val);
-      break;
-    default: assert(0);
+  
+  
+  
+  make_EHelper(cmp) {
+  	rtl_sext(&t1, &id_dest->val, id_dest->width);
+  	rtl_sext(&t2, &id_src->val, id_src->width);
+  
+  	rtl_sub(&t0, &t1, &t2);
+  	t3 = (t0 > t1);
+  	rtl_set_CF(&t3);
+  	t3 = ((((int32_t)(t1) < 0) == (((int32_t)(t2) >> 31) == 0)) && (((int32_t)(t0) < 0) != ((int32_t)(t1) < 0)));
+  	rtl_set_OF(&t3);
+  	rtl_update_ZFSF(&t0, 4);
+  
+    print_asm_template2(cmp);
   }
-
-  print_asm_template1(div);
-}
-
-make_EHelper(idiv) {
-  switch (id_dest->width) {
-    case 1:
-      rtl_lr(&t0, R_AX, 2);
-      rtl_idiv_q(&t2, &t0, &id_dest->val);
-      rtl_idiv_r(&t3, &t0, &id_dest->val);
-      rtl_sr(R_AL, &t2, 1);
-      rtl_sr(R_AH, &t3, 1);
-      break;
-    case 2:
-      rtl_lr(&t0, R_AX, 2);
-      rtl_lr(&t1, R_DX, 2);
-      rtl_shli(&t1, &t1, 16);
-      rtl_or(&t0, &t0, &t1);
-      rtl_idiv_q(&t2, &t0, &id_dest->val);
-      rtl_idiv_r(&t3, &t0, &id_dest->val);
-      rtl_sr(R_AX, &t2, 2);
-      rtl_sr(R_DX, &t3, 2);
-      break;
-    case 4:
-      rtl_lr(&t0, R_EAX, 4);
-      rtl_lr(&t1, R_EDX, 4);
-      rtl_idiv64_q(&cpu.eax, &t1, &t0, &id_dest->val);
-      rtl_idiv64_r(&cpu.edx, &t1, &t0, &id_dest->val);
-      break;
-    default: assert(0);
+  
+  make_EHelper(inc) {
+  	rtl_addi(&t2, &id_dest->val, 1);
+  	operand_write(id_dest, &t2);
+  	rtl_update_ZFSF(&t2, id_dest->width);
+  	rtl_xor(&t0, &id_dest->val, &id_src->val);
+  	rtl_not(&t0, &t0);
+  	rtl_xor(&t1, &id_dest->val, &t2);
+  	rtl_and(&t0, &t0, &t1);
+  	rtl_msb(&t0, &t0, id_dest->width);
+  	rtl_set_OF(&t0);
+  
+    print_asm_template1(inc);
+  }
+  
+  make_EHelper(dec) {
+    rtl_subi(&t2, &id_dest->val, 1);
+  	operand_write(id_dest, &t2);
+  
+  	rtl_update_ZFSF(&t2, id_dest->width);
+  
+  	rtl_xor(&t0, &id_dest->val, &id_src->val);
+  	rtl_xor(&t1, &id_dest->val, &t2);
+  	rtl_and(&t0, &t0, &t1);
+  	rtl_msb(&t0, &t0, id_dest->width);
+  	rtl_set_OF(&t0);
+  
+    print_asm_template1(dec);
+  }
+  
+  make_EHelper(neg) {
+    TODO();
+  
+    print_asm_template1(neg);
+  }
+  
+  make_EHelper(adc) {
+    rtl_add(&t2, &id_dest->val, &id_src->val);
+    rtl_setrelop(RELOP_LTU, &t3, &t2, &id_dest->val);
+    rtl_get_CF(&t1);
+    rtl_add(&t2, &t2, &t1);
+    operand_write(id_dest, &t2);
+  
+    rtl_update_ZFSF(&t2, id_dest->width);
+  
+    rtl_setrelop(RELOP_LTU, &t0, &t2, &id_dest->val);
+    rtl_or(&t0, &t3, &t0);
+    rtl_set_CF(&t0);
+  
+    rtl_xor(&t0, &id_dest->val, &id_src->val);
+    rtl_not(&t0, &t0);
+    rtl_xor(&t1, &id_dest->val, &t2);
+    rtl_and(&t0, &t0, &t1);
+    rtl_msb(&t0, &t0, id_dest->width);
+    rtl_set_OF(&t0);
+  
+    print_asm_template2(adc);
+  }
+  
+  make_EHelper(sbb) {
+    rtl_sub(&t2, &id_dest->val, &id_src->val);
+    rtl_setrelop(RELOP_LTU, &t3, &id_dest->val, &t2);
+    rtl_get_CF(&t1);
+    rtl_sub(&t2, &t2, &t1);
+    operand_write(id_dest, &t2);
+  
+    rtl_update_ZFSF(&t2, id_dest->width);
+  
+    rtl_setrelop(RELOP_LTU, &t0, &id_dest->val, &t2);
+    rtl_or(&t0, &t3, &t0);
+    rtl_set_CF(&t0);
+  
+    rtl_xor(&t0, &id_dest->val, &id_src->val);
+    rtl_xor(&t1, &id_dest->val, &t2);
+    rtl_and(&t0, &t0, &t1);
+    rtl_msb(&t0, &t0, id_dest->width);
+    rtl_set_OF(&t0);
+  
+    print_asm_template2(sbb);
+  }
+  
+  make_EHelper(mul) {
+    rtl_lr(&t0, R_EAX, id_dest->width);
+    rtl_mul_lo(&t1, &id_dest->val, &t0);
+  
+    switch (id_dest->width) {
+      case 1:
+        rtl_sr(R_AX, &t1, 2);
+        break;
+      case 2:
+        rtl_sr(R_AX, &t1, 2);
+        rtl_shri(&t1, &t1, 16);
+        rtl_sr(R_DX, &t1, 2);
+        break;
+      case 4:
+        rtl_mul_hi(&t2, &id_dest->val, &t0);
+        rtl_sr(R_EDX, &t2, 4);
+        rtl_sr(R_EAX, &t1, 4);
+        break;
+      default: assert(0);
+    }
+  
+    print_asm_template1(mul);
+  }
+  
+  // imul with one operand
+  make_EHelper(imul1) {
+    rtl_lr(&t0, R_EAX, id_dest->width);
+    rtl_imul_lo(&t1, &id_dest->val, &t0);
+  
+    switch (id_dest->width) {
+      case 1:
+        rtl_sr(R_AX, &t1, 2);
+        break;
+      case 2:
+        rtl_sr(R_AX, &t1, 2);
+        rtl_shri(&t1, &t1, 16);
+        rtl_sr(R_DX, &t1, 2);
+        break;
+      case 4:
+        rtl_imul_hi(&t2, &id_dest->val, &t0);
+        rtl_sr(R_EDX, &t2, 4);
+        rtl_sr(R_EAX, &t1, 4);
+        break;
+      default: assert(0);
+    }
+  
+    print_asm_template1(imul);
+  }
+  
+  // imul with two operands
+  make_EHelper(imul2) {
+    rtl_sext(&t0, &id_src->val, id_src->width);
+    rtl_sext(&t1, &id_dest->val, id_dest->width);
+  
+    rtl_imul_lo(&t2, &t1, &t0);
+    operand_write(id_dest, &t2);
+  
+    print_asm_template2(imul);
+  }
+  
+  // imul with three operands
+  make_EHelper(imul3) {
+    rtl_sext(&t0, &id_src->val, id_src->width);
+    rtl_sext(&t1, &id_src2->val, id_src->width);
+    rtl_sext(&id_dest->val, &id_dest->val, id_dest->width);
+  
+    rtl_imul_lo(&t2, &t1, &t0);
+    operand_write(id_dest, &t2);
+  
+    print_asm_template3(imul);
+  }
+  
+  make_EHelper(div) {
+    switch (id_dest->width) {
+      case 1:
+        rtl_lr(&t0, R_AX, 2);
+        rtl_div_q(&t2, &t0, &id_dest->val);
+        rtl_div_r(&t3, &t0, &id_dest->val);
+        rtl_sr(R_AL, &t2, 1);
+        rtl_sr(R_AH, &t3, 1);
+        break;
+      case 2:
+        rtl_lr(&t0, R_AX, 2);
+        rtl_lr(&t1, R_DX, 2);
+        rtl_shli(&t1, &t1, 16);
+        rtl_or(&t0, &t0, &t1);
+        rtl_div_q(&t2, &t0, &id_dest->val);
+        rtl_div_r(&t3, &t0, &id_dest->val);
+        rtl_sr(R_AX, &t2, 2);
+        rtl_sr(R_DX, &t3, 2);
+        break;
+      case 4:
+        rtl_lr(&t0, R_EAX, 4);
+        rtl_lr(&t1, R_EDX, 4);
+        rtl_div64_q(&cpu.eax, &t1, &t0, &id_dest->val);
+        rtl_div64_r(&cpu.edx, &t1, &t0, &id_dest->val);
+        break;
+      default: assert(0);
+    }
+  
+    print_asm_template1(div);
+  }
+  
+  make_EHelper(idiv) {
+    switch (id_dest->width) {
+      case 1:
+        rtl_lr(&t0, R_AX, 2);
+        rtl_idiv_q(&t2, &t0, &id_dest->val);
+        rtl_idiv_r(&t3, &t0, &id_dest->val);
+        rtl_sr(R_AL, &t2, 1);
+        rtl_sr(R_AH, &t3, 1);
+        break;
+      case 2:
+        rtl_lr(&t0, R_AX, 2);
+        rtl_lr(&t1, R_DX, 2);
+        rtl_shli(&t1, &t1, 16);
+        rtl_or(&t0, &t0, &t1);
+        rtl_idiv_q(&t2, &t0, &id_dest->val);
+        rtl_idiv_r(&t3, &t0, &id_dest->val);
+        rtl_sr(R_AX, &t2, 2);
+        rtl_sr(R_DX, &t3, 2);
+        break;
+      case 4:
+        rtl_lr(&t0, R_EAX, 4);
+        rtl_lr(&t1, R_EDX, 4);
+        rtl_idiv64_q(&cpu.eax, &t1, &t0, &id_dest->val);
+        rtl_idiv64_r(&cpu.edx, &t1, &t0, &id_dest->val);
+        break;
+      default: assert(0);
+    }
+  
+    print_asm_template1(idiv);
   }
 
-  print_asm_template1(idiv);
-}
-
-} // end namespace
\ No newline at end of file
+} // end namespace
diff --git a/nemu/src/cpu/exec/control.cc b/nemu/src/cpu/exec/control.cc
index 51c9f23..b4a157d 100644
--- a/nemu/src/cpu/exec/control.cc
+++ b/nemu/src/cpu/exec/control.cc
@@ -1,70 +1,72 @@
 #include "cpu/exec.h"
 #include "cpu/cc.h"
 
-make_EHelper(jmp) {
-  // the target address is calculated at the decode stage
-  rtl_j(decoding.jmp_eip);
-
-  print_asm("jmp %x", decoding.jmp_eip);
-}
-
-make_EHelper(jcc) {
-  // the target address is calculated at the decode stage
-  uint32_t cc = decoding.opcode & 0xf;
-  rtl_setcc(&t0, cc);
-  rtl_li(&t1, 0);
-  rtl_jrelop(RELOP_NE, &t0, &t1, decoding.jmp_eip);
-
-  print_asm("j%s %x", get_cc_name(cc), decoding.jmp_eip);
-}
-
-make_EHelper(jmp_rm) {
-  rtl_jr(&id_dest->val);
-
-  print_asm("jmp *%s", id_dest->str);
-}
-
-make_EHelper(call) {
-  // the target address is calculated at the decode stage
-  const bool near = true;
-  if(near) {
-    if(decoding.is_operand_size_16) {
-      throw std::runtime_error("call operand size 16 not implemented.");
-    }
-    else {
-      // operand size 32b
-      rtl_push<4>(&decoding.seq_eip);
-      rtl_j(decoding.jmp_eip);
-    }
-    decoding_set_jmp(true);
+namespace EHelperImpl {
+  make_EHelper(jmp) {
+    // the target address is calculated at the decode stage
+    rtl_j(decoding.jmp_eip);
+  
+    print_asm("jmp %x", decoding.jmp_eip);
   }
-  // TODO: support far call
-  // TODO();
-
-  print_asm("call %x", decoding.jmp_eip);
-}
-
-make_EHelper(ret) {
-  const bool near = true;
-  if(near) {
-    if(decoding.is_operand_size_16) {
-      throw std::runtime_error("call operand size 16 not implemented.");
+  
+  make_EHelper(jcc) {
+    // the target address is calculated at the decode stage
+    uint32_t cc = decoding.opcode & 0xf;
+    rtl_setcc(&t0, cc);
+    rtl_li(&t1, 0);
+    rtl_jrelop(RELOP_NE, &t0, &t1, decoding.jmp_eip);
+  
+    print_asm("j%s %x", get_cc_name(cc), decoding.jmp_eip);
+  }
+  
+  make_EHelper(jmp_rm) {
+    rtl_jr(&id_dest->val);
+  
+    print_asm("jmp *%s", id_dest->str);
+  }
+  
+  make_EHelper(call) {
+    // the target address is calculated at the decode stage
+    const bool near = true;
+    if(near) {
+      if(decoding.is_operand_size_16) {
+        throw std::runtime_error("call operand size 16 not implemented.");
+      }
+      else {
+        // operand size 32b
+        rtl_push<4>(&decoding.seq_eip);
+        rtl_j(decoding.jmp_eip);
+      }
+      decoding_set_jmp(true);
     }
-    else {
-      // operand size 32b
-      rtl_pop<4>(&cpu.eip);
+    // TODO: support far call
+    // TODO();
+  
+    print_asm("call %x", decoding.jmp_eip);
+  }
+  
+  make_EHelper(ret) {
+    const bool near = true;
+    if(near) {
+      if(decoding.is_operand_size_16) {
+        throw std::runtime_error("call operand size 16 not implemented.");
+      }
+      else {
+        // operand size 32b
+        rtl_pop<4>(&cpu.eip);
+      }
+      decoding_set_jmp(true);
     }
-    decoding_set_jmp(true);
+  
+   // TODO: support far ret
+    // TODO();
+  
+    print_asm("ret");
   }
-
- // TODO: support far ret
-  // TODO();
-
-  print_asm("ret");
-}
-
-make_EHelper(call_rm) {
-  TODO();
-
-  print_asm("call *%s", id_dest->str);
-}
+  
+  make_EHelper(call_rm) {
+    TODO();
+  
+    print_asm("call *%s", id_dest->str);
+  }
+} // end namespace
diff --git a/nemu/src/cpu/exec/data-mov.cc b/nemu/src/cpu/exec/data-mov.cc
index 6182ede..8e61839 100644
--- a/nemu/src/cpu/exec/data-mov.cc
+++ b/nemu/src/cpu/exec/data-mov.cc
@@ -1,101 +1,103 @@
 #include "cpu/exec.h"
 
-make_EHelper(mov) {
-  operand_write(id_dest, &id_src->val);
-  print_asm_template2(mov);
-}
-
-make_EHelper(push) {
-  static_assert(sizeof(paddr_t) * 8 == 32);
-  if(decoding.is_operand_size_16) {
-    // 16b push
-    rtl_push<2>(&id_dest->val);
+namespace EHelperImpl {
+  make_EHelper(mov) {
+    operand_write(id_dest, &id_src->val);
+    print_asm_template2(mov);
   }
-  else {
-    // 32b push
-    rtl_push<4>(&id_dest->val);
+  
+  make_EHelper(push) {
+    static_assert(sizeof(paddr_t) * 8 == 32);
+    if(decoding.is_operand_size_16) {
+      // 16b push
+      rtl_push<2>(&id_dest->val);
+    }
+    else {
+      // 32b push
+      rtl_push<4>(&id_dest->val);
+    }
+  
+    print_asm_template1(push);
   }
-
-  print_asm_template1(push);
-}
-
-make_EHelper(pop) {
-  static_assert(sizeof(paddr_t) * 8 == 32);
-  if(decoding.is_operand_size_16) {
-    // 16b
-    rtl_pop<2>(&id_dest->val);
+  
+  make_EHelper(pop) {
+    static_assert(sizeof(paddr_t) * 8 == 32);
+    if(decoding.is_operand_size_16) {
+      // 16b
+      rtl_pop<2>(&id_dest->val);
+    }
+    else {
+      // 32b
+      rtl_pop<4>(&id_dest->val);
+    }
+    operand_write(id_dest, &id_dest->val);
+  
+    print_asm_template1(pop);
   }
-  else {
-    // 32b
-    rtl_pop<4>(&id_dest->val);
+  
+  make_EHelper(pusha) {
+    TODO();
+  
+    print_asm("pusha");
   }
-  operand_write(id_dest, &id_dest->val);
-
-  print_asm_template1(pop);
-}
-
-make_EHelper(pusha) {
-  TODO();
-
-  print_asm("pusha");
-}
-
-make_EHelper(popa) {
-  TODO();
-
-  print_asm("popa");
-}
-
-make_EHelper(leave) {
-  rtl_mv(&cpu.esp, &cpu.ebp);
-  if(decoding.is_operand_size_16) {
-    rtlreg_t tmpReg;
-    rtl_pop<2>(&tmpReg);
-    reg_w(R_BP) = (uint16_t)tmpReg;
+  
+  make_EHelper(popa) {
+    TODO();
+  
+    print_asm("popa");
   }
-  else {
-    rtl_pop<4>(&cpu.ebp);
+  
+  make_EHelper(leave) {
+    rtl_mv(&cpu.esp, &cpu.ebp);
+    if(decoding.is_operand_size_16) {
+      rtlreg_t tmpReg;
+      rtl_pop<2>(&tmpReg);
+      reg_w(R_BP) = (uint16_t)tmpReg;
+    }
+    else {
+      rtl_pop<4>(&cpu.ebp);
+    }
+  
+    print_asm("leave");
   }
-
-  print_asm("leave");
-}
-
-make_EHelper(cltd) {
-  if (decoding.is_operand_size_16) {
-    TODO();
+  
+  make_EHelper(cltd) {
+    if (decoding.is_operand_size_16) {
+      TODO();
+    }
+    else {
+      TODO();
+    }
+  
+    print_asm(decoding.is_operand_size_16 ? "cwtl" : "cltd");
   }
-  else {
-    TODO();
+  
+  make_EHelper(cwtl) {
+    if (decoding.is_operand_size_16) {
+      TODO();
+    }
+    else {
+      TODO();
+    }
+  
+    print_asm(decoding.is_operand_size_16 ? "cbtw" : "cwtl");
   }
-
-  print_asm(decoding.is_operand_size_16 ? "cwtl" : "cltd");
-}
-
-make_EHelper(cwtl) {
-  if (decoding.is_operand_size_16) {
-    TODO();
+  
+  make_EHelper(movsx) {
+    id_dest->width = decoding.is_operand_size_16 ? 2 : 4;
+    rtl_sext(&t0, &id_src->val, id_src->width);
+    operand_write(id_dest, &t0);
+    print_asm_template2(movsx);
   }
-  else {
-    TODO();
+  
+  make_EHelper(movzx) {
+    id_dest->width = decoding.is_operand_size_16 ? 2 : 4;
+    operand_write(id_dest, &id_src->val);
+    print_asm_template2(movzx);
   }
-
-  print_asm(decoding.is_operand_size_16 ? "cbtw" : "cwtl");
-}
-
-make_EHelper(movsx) {
-  id_dest->width = decoding.is_operand_size_16 ? 2 : 4;
-  rtl_sext(&t0, &id_src->val, id_src->width);
-  operand_write(id_dest, &t0);
-  print_asm_template2(movsx);
-}
-
-make_EHelper(movzx) {
-  id_dest->width = decoding.is_operand_size_16 ? 2 : 4;
-  operand_write(id_dest, &id_src->val);
-  print_asm_template2(movzx);
-}
-
-make_EHelper(lea) {
-  operand_write(id_dest, &id_src->addr);
-  print_asm_template2(lea);
-}
+  
+  make_EHelper(lea) {
+    operand_write(id_dest, &id_src->addr);
+    print_asm_template2(lea);
+  }
+} // end namespace
diff --git a/nemu/src/cpu/exec/exec.cc b/nemu/src/cpu/exec/exec.cc
index 6698332..67ab9e7 100644
--- a/nemu/src/cpu/exec/exec.cc
+++ b/nemu/src/cpu/exec/exec.cc
@@ -28,20 +28,21 @@ static inline void idex(vaddr_t *eip, opcode_entry *e) {
   e->execute(eip);
 }
 
+namespace EHelperImpl {static make_EHelper(_2byte_esc);}
 
 #define make_group(name, item0, item1, item2, item3, item4, item5, item6, item7) \
   static opcode_entry concat(opcode_table_, name) [8] = { \
     /* 0x00 */	item0, item1, item2, item3, \
     /* 0x04 */	item4, item5, item6, item7  \
   }; \
-namespace EHelperImpl {static name { \
+namespace EHelperImpl { static make_EHelper(name) { \
   idex(eip, &concat(opcode_table_, name)[decoding.ext_opcode]); \
 }}
 
 /* 0x80, 0x81, 0x83 */
 make_group(gp1,
-    EX(add), EX(or), EX(adc), EX(sbb),
-    EX(and), EX(sub),EX(xor), EX(cmp))
+    EX(add), EX(or_), EX(adc), EX(sbb),
+    EX(and_), EX(sub),EX(xor_), EX(cmp))
 
 /* 0xc0, 0xc1, 0xd0, 0xd1, 0xd2, 0xd3 */
 make_group(gp2,
@@ -50,7 +51,7 @@ make_group(gp2,
 
 /* 0xf6, 0xf7 */
 make_group(gp3,
-    IDEX(test_I,test), EMPTY, EX(not), EX(neg),
+    IDEX(test_I,test), EMPTY, EX(not_), EX(neg),
     EX(mul), EX(imul1), EX(div), EX(idiv))
 
 /* 0xfe */
@@ -71,18 +72,18 @@ make_group(gp7,
 opcode_entry opcode_table [512] = {
   /* 0x00 */	IDEXW(G2E,add,1),IDEX(G2E,add), IDEXW(E2G,add,1), IDEX(E2G,add),
   /* 0x04 */	IDEXW(I2a,add,1), IDEX(I2a,add), EMPTY, EMPTY,
-  /* 0x08 */  IDEXW(G2E,or,1), IDEX(G2E,or), IDEXW(E2G,or,1), IDEX(E2G,or),
-  /* 0x0c */	IDEXW(I2a,or,1), IDEX(I2a,or), EMPTY, EX(_2byte_esc),
+  /* 0x08 */    IDEXW(G2E,or_,1), IDEX(G2E,or_), IDEXW(E2G,or_,1), IDEX(E2G,or_),
+  /* 0x0c */	IDEXW(I2a,or_,1), IDEX(I2a,or_), EMPTY, EX(_2byte_esc),
   /* 0x10 */	IDEXW(G2E,adc,1), IDEX(G2E,adc), IDEXW(E2G,adc,1), IDEX(E2G,adc),
   /* 0x14 */	IDEXW(I2a,adc,1), IDEX(I2a,adc), EMPTY, EMPTY,
   /* 0x18 */	IDEXW(G2E,sbb,1), IDEX(G2E,sbb), IDEXW(E2G,sbb,1), IDEX(E2G,sbb),
   /* 0x1c */	IDEXW(I2a,sbb,1), IDEX(I2a,sbb), EMPTY, EMPTY,
-  /* 0x20 */	IDEXW(G2E,and,1), IDEX(G2E,and),IDEXW(E2G,and,1), IDEX(E2G,and),
-  /* 0x24 */	IDEXW(I2a,and,1), IDEX(I2a,and), EMPTY, EMPTY,
+  /* 0x20 */	IDEXW(G2E,and_,1), IDEX(G2E,and_),IDEXW(E2G,and_,1), IDEX(E2G,and_),
+  /* 0x24 */	IDEXW(I2a,and_,1), IDEX(I2a,and_), EMPTY, EMPTY,
   /* 0x28 */	IDEXW(G2E,sub,1), IDEX(G2E,sub), IDEXW(E2G,sub,1), IDEX(E2G,sub),
   /* 0x2c */	IDEXW(I2a,sub,1),IDEX(I2a,sub), EMPTY, EMPTY,
-  /* 0x30 */	IDEXW(G2E,xor,1), IDEX(G2E,xor), IDEXW(E2G,xor,1),IDEX(E2G,xor),
-  /* 0x34 */	IDEXW(I2a,xor,1), IDEX(I2a,xor), EMPTY, EMPTY,
+  /* 0x30 */	IDEXW(G2E,xor_,1), IDEX(G2E,xor_), IDEXW(E2G,xor_,1),IDEX(E2G,xor_),
+  /* 0x34 */	IDEXW(I2a,xor_,1), IDEX(I2a,xor_), EMPTY, EMPTY,
   /* 0x38 */	IDEXW(G2E,cmp,1), IDEX(G2E,cmp), IDEXW(E2G,cmp,1), IDEX(E2G,cmp),
   /* 0x3c */	IDEXW(I2a,cmp,1), IDEX(I2a,cmp), EMPTY, EMPTY,
   /* 0x40 */	IDEX(r,inc), IDEX(r,inc), IDEX(r,inc), IDEX(r,inc),
@@ -202,14 +203,14 @@ opcode_entry opcode_table [512] = {
   /* 0xfc */	EMPTY, EMPTY, EMPTY, EMPTY
 };
 
-static make_EHelper(_2byte_esc) {
-  uint32_t opcode = instr_fetch(eip, 1) | 0x100;
-  decoding.opcode = opcode;
-  set_width(opcode_table[opcode].width);
-  idex(eip, &opcode_table[opcode]);
-}
-
 namespace EHelperImpl {
+  static make_EHelper(_2byte_esc) {
+    uint32_t opcode = instr_fetch(eip, 1) | 0x100;
+    decoding.opcode = opcode;
+    set_width(opcode_table[opcode].width);
+    idex(eip, &opcode_table[opcode]);
+  }
+
   make_EHelper(real) {
     uint32_t opcode = instr_fetch(eip, 1);
     decoding.opcode = opcode;
diff --git a/nemu/src/cpu/exec/logic.cc b/nemu/src/cpu/exec/logic.cc
index 6f0d429..764b95e 100644
--- a/nemu/src/cpu/exec/logic.cc
+++ b/nemu/src/cpu/exec/logic.cc
@@ -12,89 +12,89 @@ void sign_extend_if_required(const Operand &dest, Operand &src) {
 namespace EHelperImpl {
   using vaddr_t = uint32_t;
 
-make_EHelper(test) {
-  // `and` without write_back.
-  sign_extend_if_required(*id_dest, *id_src);
-  rtl_and(&t1, &id_dest->val, &id_src->val);
-
-  rtl_update_ZFSF(&t1, id_dest->width);
-  cpu_eflags::get<cpu_eflags::CF>() = cpu_eflags::get<cpu_eflags::OF>() = false;
-
-  print_asm_template2(test);
-}
-
-make_EHelper(and) {
-  rlib::printfln("before test, id_dest={}, src={}", *id_dest, *id_src);
-  sign_extend_if_required(*id_dest, *id_src);
-  rlib::printfln("after test, id_dest={}, src={}", *id_dest, *id_src);
-
-  rtl_and(&id_dest->val, &id_dest->val, &id_src->val);
-  operand_write(id_dest, &id_dest->val);
-
-  rtl_update_ZFSF(&id_dest->val, id_dest->width);
-  cpu_eflags::get<cpu_eflags::CF>() = cpu_eflags::get<cpu_eflags::OF>() = false;
-
-  print_asm_template2(and);
-}
-
-make_EHelper(xor) {
-  sign_extend_if_required(*id_dest, *id_src);
-
-  rtl_xor(&id_dest->val, &id_dest->val, &id_src->val);
-  operand_write(id_dest, &id_dest->val);
-
-  rtl_update_ZFSF(&id_dest->val, id_dest->width);
-  cpu_eflags::get<cpu_eflags::CF>() = cpu_eflags::get<cpu_eflags::OF>() = false;
-
-  print_asm_template2(xor);
-}
-
-make_EHelper(or) {
-  TODO();
-
-  print_asm_template2(or);
-}
-
-make_EHelper(sar) {
-  TODO();
-  // unnecessary to update CF and OF in NEMU
-
-  print_asm_template2(sar);
-}
-
-make_EHelper(shl) {
-  TODO();
-  // unnecessary to update CF and OF in NEMU
-
-  print_asm_template2(shl);
-}
-
-make_EHelper(shr) {
-  TODO();
-  // unnecessary to update CF and OF in NEMU
-
-  print_asm_template2(shr);
-}
-
-make_EHelper(setcc) {
-  uint32_t cc = decoding.opcode & 0xf;
-
-  rtl_setcc(&t2, cc);
-  operand_write(id_dest, &t2);
-
-  print_asm("set%s %s", get_cc_name(cc), id_dest->str);
-}
-
-make_EHelper(not) {
-  TODO();
-
-  print_asm_template1(not);
-}
-
-make_EHelper(rol) {
-  TODO();
-
-  print_asm_template1(rol);
-}
+  make_EHelper(test) {
+    // `and` without write_back.
+    sign_extend_if_required(*id_dest, *id_src);
+    rtl_and(&t1, &id_dest->val, &id_src->val);
+  
+    rtl_update_ZFSF(&t1, id_dest->width);
+    cpu_eflags::get<cpu_eflags::CF>() = cpu_eflags::get<cpu_eflags::OF>() = false;
+  
+    print_asm_template2(test);
+  }
+  
+  make_EHelper(and_) {
+    rlib::printfln("before test, id_dest={}, src={}", *id_dest, *id_src);
+    sign_extend_if_required(*id_dest, *id_src);
+    rlib::printfln("after test, id_dest={}, src={}", *id_dest, *id_src);
+  
+    rtl_and(&id_dest->val, &id_dest->val, &id_src->val);
+    operand_write(id_dest, &id_dest->val);
+  
+    rtl_update_ZFSF(&id_dest->val, id_dest->width);
+    cpu_eflags::get<cpu_eflags::CF>() = cpu_eflags::get<cpu_eflags::OF>() = false;
+  
+    print_asm_template2(and);
+  }
+  
+  make_EHelper(xor_) {
+    sign_extend_if_required(*id_dest, *id_src);
+  
+    rtl_xor(&id_dest->val, &id_dest->val, &id_src->val);
+    operand_write(id_dest, &id_dest->val);
+  
+    rtl_update_ZFSF(&id_dest->val, id_dest->width);
+    cpu_eflags::get<cpu_eflags::CF>() = cpu_eflags::get<cpu_eflags::OF>() = false;
+  
+    print_asm_template2(xor);
+  }
+  
+  make_EHelper(or_) {
+    TODO();
+  
+    print_asm_template2(or);
+  }
+  
+  make_EHelper(sar) {
+    TODO();
+    // unnecessary to update CF and OF in NEMU
+  
+    print_asm_template2(sar);
+  }
+  
+  make_EHelper(shl) {
+    TODO();
+    // unnecessary to update CF and OF in NEMU
+  
+    print_asm_template2(shl);
+  }
+  
+  make_EHelper(shr) {
+    TODO();
+    // unnecessary to update CF and OF in NEMU
+  
+    print_asm_template2(shr);
+  }
+  
+  make_EHelper(setcc) {
+    uint32_t cc = decoding.opcode & 0xf;
+  
+    rtl_setcc(&t2, cc);
+    operand_write(id_dest, &t2);
+  
+    print_asm("set%s %s", get_cc_name(cc), id_dest->str);
+  }
+  
+  make_EHelper(not_) {
+    TODO();
+  
+    print_asm_template1(not);
+  }
+  
+  make_EHelper(rol) {
+    TODO();
+  
+    print_asm_template1(rol);
+  }
 
-} // end namespace ehelperimpl
\ No newline at end of file
+} // end namespace ehelperimpl
diff --git a/nemu/src/cpu/exec/special.cc b/nemu/src/cpu/exec/special.cc
index 9580a48..63c2c3e 100644
--- a/nemu/src/cpu/exec/special.cc
+++ b/nemu/src/cpu/exec/special.cc
@@ -5,45 +5,49 @@ void interpret_rtl_exit(int state) {
   nemu_state = state;
 }
 
-make_EHelper(nop) {
-  print_asm("nop");
-}
-
-make_EHelper(inv) {
-  /* invalid opcode */
-
-  uint32_t temp[2];
-  vaddr_t ori_eip = cpu.eip;
-  *eip = ori_eip;
-  temp[0] = instr_fetch(eip, 4);
-  temp[1] = instr_fetch(eip, 4);
-
-  uint8_t *p = (uint8_t *)temp;
-  printf("invalid opcode(eip = 0x%08x): %02x %02x %02x %02x %02x %02x %02x %02x ...\n\n",
-      ori_eip, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
-
-  extern char logo [];
-  printf("There are two cases which will trigger this unexpected exception:\n"
-      "1. The instruction at eip = 0x%08x is not implemented.\n"
-      "2. Something is implemented incorrectly.\n", ori_eip);
-  printf("Find this eip(0x%08x) in the disassembling result to distinguish which case it is.\n\n", ori_eip);
-  printf("\33[1;31mIf it is the first case, see\n%s\nfor more details.\n\nIf it is the second case, remember:\n"
-      "* The machine is always right!\n"
-      "* Every line of untested code is always wrong!\33[0m\n\n", logo);
-
-  rtl_exit(NEMU_ABORT);
-
-  print_asm("invalid opcode");
-}
-
-make_EHelper(nemu_trap) {
-#if defined(DIFF_TEST)
-  void difftest_skip_ref();
-  difftest_skip_ref();
-#endif
-
-  rtl_exit(NEMU_END);
-
-  print_asm("nemu trap");
-  return;
-}
+extern char logo [];
+
+namespace EHelperImpl {
+
+  make_EHelper(nop) {
+    print_asm("nop");
+  }
+  
+  make_EHelper(inv) {
+    /* invalid opcode */
+  
+    uint32_t temp[2];
+    vaddr_t ori_eip = cpu.eip;
+    *eip = ori_eip;
+    temp[0] = instr_fetch(eip, 4);
+    temp[1] = instr_fetch(eip, 4);
+  
+    uint8_t *p = (uint8_t *)temp;
+    printf("invalid opcode(eip = 0x%08x): %02x %02x %02x %02x %02x %02x %02x %02x ...\n\n",
+        ori_eip, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+  
+    printf("There are two cases which will trigger this unexpected exception:\n"
+        "1. The instruction at eip = 0x%08x is not implemented.\n"
+        "2. Something is implemented incorrectly.\n", ori_eip);
+    printf("Find this eip(0x%08x) in the disassembling result to distinguish which case it is.\n\n", ori_eip);
+    printf("\33[1;31mIf it is the first case, see\n%s\nfor more details.\n\nIf it is the second case, remember:\n"
+        "* The machine is always right!\n"
+        "* Every line of untested code is always wrong!\33[0m\n\n", logo);
+  
+    rtl_exit(NEMU_ABORT);
+  
+    print_asm("invalid opcode");
+  }
+  
+  make_EHelper(nemu_trap) {
+  #if defined(DIFF_TEST)
+    void difftest_skip_ref();
+    difftest_skip_ref();
+  #endif
+  
+    rtl_exit(NEMU_END);
+  
+    print_asm("nemu trap");
+    return;
+  }
+} // end namespace
diff --git a/nemu/src/cpu/exec/system.cc b/nemu/src/cpu/exec/system.cc
index 5e13fef..c1876cf 100644
--- a/nemu/src/cpu/exec/system.cc
+++ b/nemu/src/cpu/exec/system.cc
@@ -3,60 +3,62 @@
 void difftest_skip_ref();
 void difftest_skip_dut();
 
-make_EHelper(lidt) {
-  TODO();
-
-  print_asm_template1(lidt);
-}
-
-make_EHelper(mov_r2cr) {
-  TODO();
-
-  print_asm("movl %%%s,%%cr%d", reg_name(id_src->reg, 4), id_dest->reg);
-}
-
-make_EHelper(mov_cr2r) {
-  TODO();
-
-  print_asm("movl %%cr%d,%%%s", id_src->reg, reg_name(id_dest->reg, 4));
-
-#if defined(DIFF_TEST)
-  difftest_skip_ref();
-#endif
-}
-
-make_EHelper(int) {
-  TODO();
-
-  print_asm("int %s", id_dest->str);
-
-#if defined(DIFF_TEST) && defined(DIFF_TEST_QEMU)
-  difftest_skip_dut();
-#endif
-}
-
-make_EHelper(iret) {
-  TODO();
-
-  print_asm("iret");
-}
-
-make_EHelper(in) {
-  TODO();
-
-  print_asm_template2(in);
-
-#if defined(DIFF_TEST)
-  difftest_skip_ref();
-#endif
-}
-
-make_EHelper(out) {
-  TODO();
-
-  print_asm_template2(out);
-
-#if defined(DIFF_TEST)
-  difftest_skip_ref();
-#endif
-}
+namespace EHelperImpl {
+  make_EHelper(lidt) {
+    TODO();
+  
+    print_asm_template1(lidt);
+  }
+  
+  make_EHelper(mov_r2cr) {
+    TODO();
+  
+    print_asm("movl %%%s,%%cr%d", reg_name(id_src->reg, 4), id_dest->reg);
+  }
+  
+  make_EHelper(mov_cr2r) {
+    TODO();
+  
+    print_asm("movl %%cr%d,%%%s", id_src->reg, reg_name(id_dest->reg, 4));
+  
+  #if defined(DIFF_TEST)
+    difftest_skip_ref();
+  #endif
+  }
+  
+  make_EHelper(int_) {
+    TODO();
+  
+    print_asm("int %s", id_dest->str);
+  
+  #if defined(DIFF_TEST) && defined(DIFF_TEST_QEMU)
+    difftest_skip_dut();
+  #endif
+  }
+  
+  make_EHelper(iret) {
+    TODO();
+  
+    print_asm("iret");
+  }
+  
+  make_EHelper(in) {
+    TODO();
+  
+    print_asm_template2(in);
+  
+  #if defined(DIFF_TEST)
+    difftest_skip_ref();
+  #endif
+  }
+  
+  make_EHelper(out) {
+    TODO();
+  
+    print_asm_template2(out);
+  
+  #if defined(DIFF_TEST)
+    difftest_skip_ref();
+  #endif
+  }
+} // end namespace
-- 
GitLab