Reduce SVM1 address decoding indirection.
authorTaylor R Campbell <campbell@mumble.net>
Mon, 7 Oct 2013 22:35:16 +0000 (22:35 +0000)
committerTaylor R Campbell <campbell@mumble.net>
Mon, 7 Oct 2013 22:35:23 +0000 (22:35 +0000)
This must have hammered horrendously on the CPU's branch target
predictor.  No measurements yet but I'm sure SVM1 should be a lot
faster now.

src/microcode/svm1-interp.c

index 90e8d5e1f752ac2c7f8199d227537a7eeb34fa56..1f3fa064065b4267a3b8c11902eecaf07d572c56 100644 (file)
@@ -128,27 +128,17 @@ static long svm1_result;
 
 #define        ILL EXIT_VM (ERR_COMPILED_CODE_ERROR)
 
-typedef struct address_s address_t;
-typedef word_t address_value_t (address_t *);
-typedef bool address_decoder_t (address_t *);
+typedef bool address_decoder_t (word_t *);
 static address_decoder_t * address_decoders [256];
 
-struct address_s
-{
-  wreg_t r1;
-  wreg_t r2;
-  word_t n1;
-  long n2;
-  address_value_t * value;
-};
-#define ADDRESS_VALUE(name) ((name.value) (&name))
+#define ADDRESS_VALUE(name) name
 
 #define DEFINE_ADDRESS_DECODER(name)                                   \
-  static bool decode_addr_##name (address_t * address)
-#define ADDRESS_DECODED return (true)
+  static bool decode_addr_##name (word_t * address)
+#define ADDRESS_DECODED(addr) (*address) = (addr); return (true)
 #define DECODE_ADDRESS(name)                                           \
-  address_t name; if (predict_false (! (decode_address (&name)))) ILL
-static bool decode_address (address_t *);
+  word_t name; if (predict_false (! (decode_address (&name)))) ILL
+static bool decode_address (word_t *);
 
 typedef bool trap_0_t (void);
 typedef bool trap_1_t (wreg_t);
@@ -1235,328 +1225,273 @@ DEFINE_BINARY_FR (atan2, ATAN2, atan2)
 /* Address decoders */
 
 static inline bool
-decode_address (address_t * address)
+decode_address (word_t * address)
 {
   return ((* (address_decoders[NEXT_BYTE])) (address));
 }
 
 static bool
-illegal_address (address_t * address)
+illegal_address (word_t * address)
 {
   (void) address;              /* ignore */
   return (false);
 }
 
 static word_t
-offset_address_value (address_t * address)
+offset_address_value (wreg_t base, word_t offset, unsigned int scale)
 {
-  return ((WREG_REF (address->r1)) + (address->n1));
+  return ((WREG_REF (base)) + (offset * scale));
 }
 
+#define MAKE_OFFSET_ADDRESS(base, offset, scale)                       \
+  ADDRESS_DECODED (offset_address_value ((base), (offset), (scale)))
+
 DEFINE_ADDRESS_DECODER (indir)
 {
   DECODE_SVM1_ADDR_INDIR (base);
-  (address->r1) = base;
-  (address->n1) = 0;
-  (address->value) = offset_address_value;
-  ADDRESS_DECODED;
-}
-
-#define MAKE_OFFSET_ADDRESS(base, offset, scale)                       \
-{                                                                      \
-  (address->r1) = (base);                                              \
-  (address->n1) = ((offset) * (scale));                                        \
-  (address->value) = offset_address_value;                             \
+  MAKE_OFFSET_ADDRESS (base, 0, 0);
 }
 
 DEFINE_ADDRESS_DECODER (offset_s8_b)
 {
   DECODE_SVM1_ADDR_OFFSET_S8_B (base, offset);
   MAKE_OFFSET_ADDRESS (base, offset, SBYTE);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (offset_s8_w)
 {
   DECODE_SVM1_ADDR_OFFSET_S8_W (base, offset);
   MAKE_OFFSET_ADDRESS (base, offset, SWORD);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (offset_s8_f)
 {
   DECODE_SVM1_ADDR_OFFSET_S8_F (base, offset);
   MAKE_OFFSET_ADDRESS (base, offset, SFLOAT);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (offset_s16_b)
 {
   DECODE_SVM1_ADDR_OFFSET_S16_B (base, offset);
   MAKE_OFFSET_ADDRESS (base, offset, SBYTE);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (offset_s16_w)
 {
   DECODE_SVM1_ADDR_OFFSET_S16_W (base, offset);
   MAKE_OFFSET_ADDRESS (base, offset, SWORD);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (offset_s16_f)
 {
   DECODE_SVM1_ADDR_OFFSET_S16_F (base, offset);
   MAKE_OFFSET_ADDRESS (base, offset, SFLOAT);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (offset_s32_b)
 {
   DECODE_SVM1_ADDR_OFFSET_S32_B (base, offset);
   MAKE_OFFSET_ADDRESS (base, offset, SBYTE);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (offset_s32_w)
 {
   DECODE_SVM1_ADDR_OFFSET_S32_W (base, offset);
   MAKE_OFFSET_ADDRESS (base, offset, SWORD);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (offset_s32_f)
 {
   DECODE_SVM1_ADDR_OFFSET_S32_F (base, offset);
   MAKE_OFFSET_ADDRESS (base, offset, SFLOAT);
-  ADDRESS_DECODED;
 }
 
-static word_t
-indexed_address_value (address_t * address)
+static inline word_t
+indexed_address_value (wreg_t base, word_t offset, unsigned int oscale,
+                      wreg_t index, unsigned int iscale)
 {
   return
-    ((WREG_REF (address->r1))
-     + (address->n1)
-     + ((WREG_REF (address->r2)) * (address->n2)));
+    ((WREG_REF (base))
+     + (offset * oscale)
+     + ((WREG_REF (index)) * iscale));
 }
 
 #define MAKE_INDEXED_ADDRESS(base, offset, oscale, index, iscale)      \
-{                                                                      \
-  (address->r1) = (base);                                              \
-  (address->n1) = ((offset) * (oscale));                               \
-  (address->r2) = (index);                                             \
-  (address->n2) = (iscale);                                            \
-  (address->value) = indexed_address_value;                            \
-}
+  ADDRESS_DECODED                                                      \
+    (indexed_address_value ((base), (offset), (oscale), (index), (iscale)))
 
 DEFINE_ADDRESS_DECODER (index_b_b)
 {
   DECODE_SVM1_ADDR_INDEX_B_B (base, offset, index);
   MAKE_INDEXED_ADDRESS (base, offset, SBYTE, index, SBYTE);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (index_b_w)
 {
   DECODE_SVM1_ADDR_INDEX_B_W (base, offset, index);
   MAKE_INDEXED_ADDRESS (base, offset, SBYTE, index, SWORD);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (index_b_f)
 {
   DECODE_SVM1_ADDR_INDEX_B_F (base, offset, index);
   MAKE_INDEXED_ADDRESS (base, offset, SBYTE, index, SFLOAT);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (index_w_b)
 {
   DECODE_SVM1_ADDR_INDEX_W_B (base, offset, index);
   MAKE_INDEXED_ADDRESS (base, offset, SWORD, index, SBYTE);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (index_w_w)
 {
   DECODE_SVM1_ADDR_INDEX_W_W (base, offset, index);
   MAKE_INDEXED_ADDRESS (base, offset, SWORD, index, SWORD);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (index_w_f)
 {
   DECODE_SVM1_ADDR_INDEX_W_F (base, offset, index);
   MAKE_INDEXED_ADDRESS (base, offset, SWORD, index, SFLOAT);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (index_f_b)
 {
   DECODE_SVM1_ADDR_INDEX_F_B (base, offset, index);
   MAKE_INDEXED_ADDRESS (base, offset, SFLOAT, index, SBYTE);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (index_f_w)
 {
   DECODE_SVM1_ADDR_INDEX_F_W (base, offset, index);
   MAKE_INDEXED_ADDRESS (base, offset, SFLOAT, index, SWORD);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (index_f_f)
 {
   DECODE_SVM1_ADDR_INDEX_F_F (base, offset, index);
   MAKE_INDEXED_ADDRESS (base, offset, SFLOAT, index, SFLOAT);
-  ADDRESS_DECODED;
 }
 
-static word_t
-preinc_address_value (address_t * address)
+static inline word_t
+preinc_address_value (wreg_t reg, signed int incr)
 {
-  WREG_SET ((address->r1), ((WREG_REF (address->r1)) + (address->n2)));
-  return (WREG_REF (address->r1));
+  WREG_SET (reg, ((WREG_REF (reg)) + incr));
+  return (WREG_REF (reg));
 }
 
 #define MAKE_PREINC_ADDRESS(base, scale)                               \
-{                                                                      \
-  (address->r1) = (base);                                              \
-  (address->n2) = (scale);                                             \
-  (address->value) = preinc_address_value;                             \
-}
+  ADDRESS_DECODED (preinc_address_value ((base), (scale)))
 
 DEFINE_ADDRESS_DECODER (predec_b)
 {
   DECODE_SVM1_ADDR_PREDEC_B (base);
-  MAKE_PREINC_ADDRESS (base, (- SBYTE));
-  ADDRESS_DECODED;
+  MAKE_PREINC_ADDRESS (base, (- ((signed) SBYTE)));
 }
 
 DEFINE_ADDRESS_DECODER (predec_w)
 {
   DECODE_SVM1_ADDR_PREDEC_W (base);
-  MAKE_PREINC_ADDRESS (base, (- SWORD));
-  ADDRESS_DECODED;
+  MAKE_PREINC_ADDRESS (base, (- ((signed) SWORD)));
 }
 
 DEFINE_ADDRESS_DECODER (predec_f)
 {
   DECODE_SVM1_ADDR_PREDEC_F (base);
-  MAKE_PREINC_ADDRESS (base, (- SFLOAT));
-  ADDRESS_DECODED;
+  MAKE_PREINC_ADDRESS (base, (- ((signed) SFLOAT)));
 }
 
 DEFINE_ADDRESS_DECODER (preinc_b)
 {
   DECODE_SVM1_ADDR_PREINC_B (base);
   MAKE_PREINC_ADDRESS (base, SBYTE);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (preinc_w)
 {
   DECODE_SVM1_ADDR_PREINC_W (base);
   MAKE_PREINC_ADDRESS (base, SWORD);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (preinc_f)
 {
   DECODE_SVM1_ADDR_PREINC_F (base);
   MAKE_PREINC_ADDRESS (base, SFLOAT);
-  ADDRESS_DECODED;
 }
 
-static word_t
-postinc_address_value (address_t * address)
+static inline word_t
+postinc_address_value (wreg_t reg, signed int incr)
 {
-  word_t value = (WREG_REF (address->r1));
-  WREG_SET ((address->r1), ((WREG_REF (address->r1)) + (address->n2)));
+  word_t value = (WREG_REF (reg));
+  WREG_SET (reg, ((WREG_REF (reg)) + incr));
   return (value);
 }
 
 #define MAKE_POSTINC_ADDRESS(base, scale)                              \
-{                                                                      \
-  (address->r1) = (base);                                              \
-  (address->n2) = (scale);                                             \
-  (address->value) = postinc_address_value;                            \
-}
+  ADDRESS_DECODED (postinc_address_value ((base), (scale)))
 
 DEFINE_ADDRESS_DECODER (postdec_b)
 {
   DECODE_SVM1_ADDR_POSTDEC_B (base);
-  MAKE_POSTINC_ADDRESS (base, (- SBYTE));
-  ADDRESS_DECODED;
+  MAKE_POSTINC_ADDRESS (base, (- ((signed) SBYTE)));
 }
 
 DEFINE_ADDRESS_DECODER (postdec_w)
 {
   DECODE_SVM1_ADDR_POSTDEC_W (base);
-  MAKE_POSTINC_ADDRESS (base, (- SWORD));
-  ADDRESS_DECODED;
+  MAKE_POSTINC_ADDRESS (base, (- ((signed) SWORD)));
 }
 
 DEFINE_ADDRESS_DECODER (postdec_f)
 {
   DECODE_SVM1_ADDR_POSTDEC_F (base);
-  MAKE_POSTINC_ADDRESS (base, (- SFLOAT));
-  ADDRESS_DECODED;
+  MAKE_POSTINC_ADDRESS (base, (- ((signed) SFLOAT)));
 }
 
 DEFINE_ADDRESS_DECODER (postinc_b)
 {
   DECODE_SVM1_ADDR_POSTINC_B (base);
   MAKE_POSTINC_ADDRESS (base, SBYTE);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (postinc_w)
 {
   DECODE_SVM1_ADDR_POSTINC_W (base);
   MAKE_POSTINC_ADDRESS (base, SWORD);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (postinc_f)
 {
   DECODE_SVM1_ADDR_POSTINC_F (base);
   MAKE_POSTINC_ADDRESS (base, SFLOAT);
-  ADDRESS_DECODED;
 }
 
-static word_t
-pcr_value (address_t * address)
+static inline word_t
+pcr_value (word_t offset)
 {
-  return (((word_t) PC) + (address->n2));
+  return (((word_t) PC) + offset);
 }
 
 #define MAKE_PCR_ADDRESS(offset)                                       \
-{                                                                      \
-  (address->n2) = (offset);                                            \
-  (address->value) = pcr_value;                                                \
-}
+  ADDRESS_DECODED (pcr_value (offset))
 
 DEFINE_ADDRESS_DECODER (pcr_s8)
 {
   DECODE_SVM1_ADDR_PCR_S8 (offset);
   MAKE_PCR_ADDRESS (offset);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (pcr_s16)
 {
   DECODE_SVM1_ADDR_PCR_S16 (offset);
   MAKE_PCR_ADDRESS (offset);
-  ADDRESS_DECODED;
 }
 
 DEFINE_ADDRESS_DECODER (pcr_s32)
 {
   DECODE_SVM1_ADDR_PCR_S32 (offset);
   MAKE_PCR_ADDRESS (offset);
-  ADDRESS_DECODED;
 }
 \f
 #define INITIALIZE_DECODER_TABLE(table, initial_value) do              \