]> granicus.if.org Git - yasm/commitdiff
* arch.h (yasm_arch_check_id_retval): Add YASM_ARCH_CHECK_ID_REGGROUP to
authorPeter Johnson <peter@tortall.net>
Sun, 25 Sep 2005 03:20:54 +0000 (03:20 -0000)
committerPeter Johnson <peter@tortall.net>
Sun, 25 Sep 2005 03:20:54 +0000 (03:20 -0000)
represent a register group (e.g. indexed registers).
(yasm_arch_reggroup_get_reg): New function to get a specific register from
a register group and index.
(yasm_arch_module): Add module version of yasm_arch_reggroup_get_reg().

* lc3barch.c (lc3b_reggroup_get_reg): Implement.
(yasm_lc3b_LTX_arch): Point to implementation.
* x86arch.c (x86_reggroup_get_reg, yasm_x86_LTX_arch): Likewise.

svn path=/trunk/yasm/; revision=1234

libyasm/arch.h
modules/arch/lc3b/lc3barch.c
modules/arch/x86/x86arch.c

index 03f66f07ed33f98cbde28f2253dda61a6a774c4b..002b9208be91861764aff3e53e043221db251518 100644 (file)
@@ -40,6 +40,7 @@ typedef enum {
     YASM_ARCH_CHECK_ID_INSN,           /**< An instruction. */
     YASM_ARCH_CHECK_ID_PREFIX,         /**< An instruction prefix. */
     YASM_ARCH_CHECK_ID_REG,            /**< A register. */
+    YASM_ARCH_CHECK_ID_REGGROUP,       /**< A register group. */
     YASM_ARCH_CHECK_ID_SEGREG,/**< a segment register (for memory overrides). */
     YASM_ARCH_CHECK_ID_TARGETMOD       /**< A target modifier (for jumps) */
 } yasm_arch_check_id_retval;
@@ -179,6 +180,12 @@ typedef struct yasm_arch_module {
      */
     unsigned int (*get_reg_size) (yasm_arch *arch, unsigned long reg);
 
+    /** Module-level implementation of yasm_arch_reggroup_get_reg().
+     * Call yasm_arch_reggroup_get_reg() instead of calling this function.
+     */
+    unsigned long (*reggroup_get_reg) (yasm_arch *arch, unsigned long reggroup,
+                                      unsigned long regindex);
+
     /** Module-level implementation of yasm_arch_reg_print().
      * Call yasm_arch_reg_print() instead of calling this function.
      */
@@ -425,6 +432,18 @@ int yasm_arch_intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
  */
 unsigned int yasm_arch_get_reg_size(yasm_arch *arch, unsigned long reg);
 
+/** Get a specific register of a register group, based on the register
+ * group and the index within the group.
+ * \param arch         architecture
+ * \param reggroup     register group
+ * \param regindex     register index
+ * \return 0 if regindex is not valid for that register group, otherwise the
+ *         specific register value.
+ */
+unsigned long yasm_arch_reggroup_get_reg(yasm_arch *arch,
+                                        unsigned long reggroup,
+                                        unsigned long regindex);
+
 /** Print a register.  For debugging purposes.
  * \param arch         architecture
  * \param reg          register
index 5c621db587f81e34debe2d0533ef1d72ad85f159..9e3c61127dc9fabc9a9f198d38efdadc0d43bb7d 100644 (file)
@@ -95,6 +95,14 @@ lc3b_get_reg_size(/*@unused@*/ yasm_arch *arch, /*@unused@*/ unsigned long reg)
     return 2;
 }
 
+static unsigned long
+lc3b_reggroup_get_reg(/*@unused@*/ yasm_arch *arch,
+                     /*@unused@*/ unsigned long reggroup,
+                     /*@unused@*/ unsigned long regindex)
+{
+    return 0;
+}
+
 static void
 lc3b_reg_print(/*@unused@*/ yasm_arch *arch, unsigned long reg, FILE *f)
 {
@@ -139,6 +147,7 @@ yasm_arch_module yasm_lc3b_LTX_arch = {
     yasm_lc3b__intnum_fixup_rel,
     yasm_lc3b__intnum_tobytes,
     lc3b_get_reg_size,
+    lc3b_reggroup_get_reg,
     lc3b_reg_print,
     NULL,      /*yasm_lc3b__segreg_print*/
     lc3b_ea_create_expr,
index 6ace1e32cd47bc3badecb7baa4476363963d2c63..eed01ce87eb048058d718fe0f9aa5ffaf45fc8d8 100644 (file)
@@ -151,6 +151,30 @@ yasm_x86__get_reg_size(yasm_arch *arch, unsigned long reg)
     return 0;
 }
 
+static unsigned long
+x86_reggroup_get_reg(yasm_arch *arch, unsigned long reggroup,
+                    unsigned long regindex)
+{
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
+    switch ((x86_expritem_reg_size)(reggroup & ~0xFUL)) {
+       case X86_XMMREG:
+           if (arch_x86->mode_bits == 64) {
+               if (regindex > 15)
+                   return 0;
+               return reggroup | (regindex & 15);
+           }
+           /*@fallthrough@*/
+       case X86_MMXREG:
+       case X86_FPUREG:
+           if (regindex > 7)
+               return 0;
+           return reggroup | (regindex & 7);
+       default:
+           yasm_internal_error(N_("bad register group"));
+    }
+    return 0;
+}
+
 static void
 x86_reg_print(yasm_arch *arch, unsigned long reg, FILE *f)
 {
@@ -241,6 +265,7 @@ yasm_arch_module yasm_x86_LTX_arch = {
     yasm_x86__intnum_fixup_rel,
     yasm_x86__intnum_tobytes,
     yasm_x86__get_reg_size,
+    x86_reggroup_get_reg,
     x86_reg_print,
     x86_segreg_print,
     yasm_x86__ea_create_expr,