i86: use fake hard regs in register pairs to represent SImode
authorDaniel Verkamp <daniel.verkamp@gmail.com>
Mon, 13 Aug 2007 16:44:38 +0000 (12:44 -0400)
committerDaniel Verkamp <daniel.verkamp@gmail.com>
Mon, 13 Aug 2007 16:44:38 +0000 (12:44 -0400)
gcc/config/i86/i86.c
gcc/config/i86/i86.h

index ae2261a..d36ed18 100644 (file)
@@ -39,8 +39,9 @@ static void i86_function_epilogue (FILE *, HOST_WIDE_INT);
 static void i86_file_start (void);
 static rtx  i86_function_value (tree, tree, bool);
 
-enum reg_class regclass_map[] = { AREG, DREG, CREG, BREG,
-                                 SIREG, DIREG, BPREG, GENERAL_REGS };
+const enum reg_class regclass_map[] = { AREG, AREG,  DREG, DREG,  CREG, CREG,
+                                        BREG, BREG,  SIREG, SIREG,  DIREG, DIREG,
+                                        BPREG, BPREG,  GENERAL_REGS, GENERAL_REGS };
 
 static const char *register_names[] = REGISTER_NAMES;
 
index 5e3f432..cc900c1 100644 (file)
@@ -49,26 +49,52 @@ do {                                        \
 
 /* Registers */
 
-#define REG_AX 0
-#define REG_DX 1
-#define REG_CX 2
-#define REG_BX 3
-#define REG_SI 4
-#define REG_DI 5
-#define REG_BP 6
-#define REG_SP 7
+/* All registers are represented as 16-bit regs, 
+   using register pairs to represent the 32-bit extended regs.
+
+   The upper halves of the extended regs are called REG_U*.  They cannot be 
+   allocated except as part of a register pair.
+
+   For example, %eax is represented as regs 0 and 1 (REG_AX and REG_UAX).
+*/
+
+#define REG_AX  0
+#define REG_UAX 1
+
+#define REG_DX  2
+#define REG_UDX 3
+
+#define REG_CX  4
+#define REG_UCX 5
+
+#define REG_BX  6
+#define REG_UBX 7
+
+#define REG_SI  8
+#define REG_USI 9
+
+#define REG_DI  10
+#define REG_UDI 11
+
+#define REG_BP  12
+#define REG_UBP 13
+
+#define REG_SP  14
+#define REG_USP 15
+
+#define I86_REG_UPPER_P(REGNO) ((REGNO) & 1)
 
 /* Register Basics */
-#define FIRST_PSEUDO_REGISTER  (REG_SP + 1)
-#define FIXED_REGISTERS                { 0, 0, 0, 0, 0, 0, 0, 1 }
-#define CALL_USED_REGISTERS    { 1, 1, 1, 1, 0, 0, 0, 1 }
+#define FIRST_PSEUDO_REGISTER  (REG_SP + 2)
+#define FIXED_REGISTERS                { 0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  1, 1 }
+#define CALL_USED_REGISTERS    { 1, 1,  1, 1,  1, 1,  1, 1,  0, 0,  0, 0,  0, 0,  1, 1 }
 
 /* Order of Allocation of Registers */
 #define REG_ALLOC_ORDER                { REG_AX, REG_DX, REG_CX, REG_BX, REG_SI, REG_DI, REG_BP, REG_SP }
 
 /* How Values Fit in Registers */
 #define HARD_REGNO_NREGS(REGNO, MODE) ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-#define HARD_REGNO_MODE_OK(REGNO, MODE) ((REGNO) < REG_SI ? 1 : (int) (MODE) != (int) QImode)
+#define HARD_REGNO_MODE_OK(REGNO, MODE) (I86_REG_UPPER_P(REGNO) ? 0 : ((REGNO) < REG_SI ? 1 : (int) (MODE) != (int) QImode))
 #define MODES_TIEABLE_P(MODE1, MODE2) ((MODE1) == (MODE2))
 
 /* Register Classes */
@@ -104,21 +130,21 @@ enum reg_class
    "ALL_REGS" }
 
 #define REG_CLASS_CONTENTS \
-{   { 0x00 },                  \
-    { 0x01 }, { 0x02 }, { 0x04 }, { 0x08 },    \
-    { 0x10 }, { 0x20 }, { 0x40 },              \
-    { 0x03 },                  \
-    { 0x0f },                  \
-    { 0x30 },                  \
-    { 0x48 },                  \
-    { 0x78 },                  \
-    { 0xff },                  \
-    { 0xff }                   \
+{   { 0 },                                                              \
+    { 3 << REG_AX }, { 3 << REG_DX }, { 3 << REG_CX }, { 3 << REG_BX }, \
+    { 3 << REG_SI }, { 3 << REG_DI }, { 3 << REG_BP },                  \
+    { (1 << REG_AX) | (1 << REG_DX) },                                  \
+    { (1 << REG_AX) | (1 << REG_BX) | (1 << REG_CX) | (1 << REG_DX) },  \
+    { (1 << REG_SI) | (1 << REG_DI) },                                  \
+    { (1 << REG_BX) | (1 << REG_BP) },                                  \
+    { (1 << REG_SI) | (1 << REG_DI) | (1 << REG_BX) | (1 << REG_BP) },  \
+    { (1 << REG_AX) | (1 << REG_BX) | (1 << REG_CX) | (1 << REG_DX) | (1 << REG_SI) | (1 << REG_DI) }, \
+    { 0xff }                                                            \
 }
 
 #define CLASS_LIKELY_SPILLED_P(CLASS) 0
 
-extern enum reg_class regclass_map[];  /* smallest class containing REGNO */
+extern const enum reg_class regclass_map[];    /* smallest class containing REGNO */
 #define REGNO_REG_CLASS(REGNO)         (regclass_map[REGNO])
 
 #define BASE_REG_CLASS         ADDRESS_REGS
@@ -288,7 +314,7 @@ extern enum reg_class regclass_map[];       /* smallest class containing REGNO */
 
 /* Output of Assembler Instructions */
 
-#define REGISTER_NAMES {"ax", "dx", "cx", "bx", "si", "di", "bp", "sp"}
+#define REGISTER_NAMES {"ax", "uax", "dx", "udx", "cx", "ucx", "bx", "ubx", "si", "usi", "di", "udi", "bp", "ubp", "sp", "usp"}
 
 #define PRINT_OPERAND(s,x,c) i86_print_operand(s,x,c)
 #define PRINT_OPERAND_ADDRESS(s,x) i86_print_operand_address(s,x)