/* Default text to print if an instruction isn't recognized. */
#define UNKNOWN_INSN_MSG _("*unknown*")
+/* Used by the ifield rtx function. */
+#define FLD(f) (fields->f)
+
static int extract_normal
PARAMS ((CGEN_OPCODE_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
- unsigned int, int, int, int, bfd_vma, long *));
+ unsigned int, unsigned int, unsigned int, unsigned int,
+ unsigned int, unsigned int, bfd_vma, long *));
static void print_normal
PARAMS ((CGEN_OPCODE_DESC, PTR, long, unsigned int, bfd_vma, int));
static void print_address
PARAMS ((CGEN_OPCODE_DESC, bfd_vma, disassemble_info *));
\f
/* -- disassembler routines inserted here */
+/* -- dis.c */
+
+static void
+print_register_list (dis_info, value, offset, load_store)
+ PTR dis_info;
+ long value;
+ long offset;
+ int load_store; /* 0 == load, 1 == store */
+{
+ disassemble_info *info = dis_info;
+ int mask;
+ int index = 0;
+ char* comma = "";
+
+ if (load_store)
+ mask = 0x80;
+ else
+ mask = 1;
+
+ if (value & mask)
+ {
+ (*info->fprintf_func) (info->stream, "r%i", index + offset);
+ comma = ",";
+ }
+
+ for (index = 1; index <= 7; ++index)
+ {
+ if (load_store)
+ mask >>= 1;
+ else
+ mask <<= 1;
+
+ if (value & mask)
+ {
+ (*info->fprintf_func) (info->stream, "%sr%i", comma, index + offset);
+ comma = ",";
+ }
+ }
+}
+
+static void
+print_hi_register_list_ld (od, dis_info, value, attrs, pc, length)
+ CGEN_OPCODE_DESC od;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ print_register_list (dis_info, value, 8, 0/*load*/);
+}
+
+static void
+print_low_register_list_ld (od, dis_info, value, attrs, pc, length)
+ CGEN_OPCODE_DESC od;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ print_register_list (dis_info, value, 0, 0/*load*/);
+}
+
+static void
+print_hi_register_list_st (od, dis_info, value, attrs, pc, length)
+ CGEN_OPCODE_DESC od;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ print_register_list (dis_info, value, 8, 1/*store*/);
+}
+
+static void
+print_low_register_list_st (od, dis_info, value, attrs, pc, length)
+ CGEN_OPCODE_DESC od;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ print_register_list (dis_info, value, 0, 1/*store*/);
+}
+
+static void
+print_m4 (od, dis_info, value, attrs, pc, length)
+ CGEN_OPCODE_DESC od;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ disassemble_info *info = (disassemble_info *) dis_info;
+ (*info->fprintf_func) (info->stream, "%ld", value);
+}
+/* -- */
/* Main entry point for operand extraction.
bfd_vma pc;
{
int length;
+ unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
switch (opindex)
{
case FR30_OPERAND_RI :
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Ri);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
break;
case FR30_OPERAND_RJ :
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rj);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
+ break;
+ case FR30_OPERAND_RIC :
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
+ break;
+ case FR30_OPERAND_RJC :
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
+ break;
+ case FR30_OPERAND_CRI :
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
+ break;
+ case FR30_OPERAND_CRJ :
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
break;
case FR30_OPERAND_RS1 :
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rs1);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
break;
case FR30_OPERAND_RS2 :
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rs2);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
break;
case FR30_OPERAND_R13 :
- length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
+ length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
break;
case FR30_OPERAND_R14 :
- length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
+ length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
break;
case FR30_OPERAND_R15 :
- length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
+ length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
break;
case FR30_OPERAND_PS :
- length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
+ length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
break;
case FR30_OPERAND_U4 :
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_u4);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, pc, & fields->f_u4);
break;
- case FR30_OPERAND_M4 :
- {
- long value;
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & value);
- value = ((value) | ((! (15))));
- fields->f_m4 = value;
- }
+ case FR30_OPERAND_U4C :
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
break;
case FR30_OPERAND_U8 :
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_u8);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_u8);
break;
case FR30_OPERAND_I8 :
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_i8);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_i8);
break;
case FR30_OPERAND_UDISP6 :
{
long value;
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & value);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, pc, & value);
value = ((value) << (2));
fields->f_udisp6 = value;
}
break;
case FR30_OPERAND_DISP8 :
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_disp8);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
break;
case FR30_OPERAND_DISP9 :
{
long value;
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, pc, & value);
value = ((value) << (1));
fields->f_disp9 = value;
}
case FR30_OPERAND_DISP10 :
{
long value;
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, pc, & value);
value = ((value) << (2));
fields->f_disp10 = value;
}
case FR30_OPERAND_S10 :
{
long value;
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 8, 8, 16, total_length, pc, & value);
value = ((value) << (2));
fields->f_s10 = value;
}
case FR30_OPERAND_U10 :
{
long value;
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & value);
value = ((value) << (2));
fields->f_u10 = value;
}
break;
case FR30_OPERAND_I32 :
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 32, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_i32);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
+ break;
+ case FR30_OPERAND_M4 :
+ {
+ long value;
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, pc, & value);
+ value = ((value) | (((-1) << (4))));
+ fields->f_m4 = value;
+ }
+ break;
+ case FR30_OPERAND_I20 :
+ {
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED)|(1<<CGEN_OPERAND_VIRTUAL), 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED)|(1<<CGEN_OPERAND_VIRTUAL), 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
+do {
+ FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
+} while (0);
+ }
break;
case FR30_OPERAND_DIR8 :
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_dir8);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
break;
case FR30_OPERAND_DIR9 :
{
long value;
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & value);
value = ((value) << (1));
fields->f_dir9 = value;
}
case FR30_OPERAND_DIR10 :
{
long value;
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & value);
value = ((value) << (2));
fields->f_dir10 = value;
}
case FR30_OPERAND_LABEL9 :
{
long value;
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_SIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
- value = ((((value) << (1))) + (((pc) & (-2))));
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 8, 16, total_length, pc, & value);
+ value = ((((value) << (1))) + (((pc) + (2))));
fields->f_rel9 = value;
}
break;
case FR30_OPERAND_LABEL12 :
{
long value;
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_SIGNED), 5, 11, CGEN_FIELDS_BITSIZE (fields), pc, & value);
- value = ((((value) << (1))) + (((pc) & (-2))));
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 5, 11, 16, total_length, pc, & value);
+ value = ((((value) << (1))) + (((pc) + (2))));
fields->f_rel12 = value;
}
break;
+ case FR30_OPERAND_REGLIST_LOW_LD :
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
+ break;
+ case FR30_OPERAND_REGLIST_HI_LD :
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
+ break;
+ case FR30_OPERAND_REGLIST_LOW_ST :
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
+ break;
+ case FR30_OPERAND_REGLIST_HI_ST :
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
+ break;
case FR30_OPERAND_CC :
- length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_cc);
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 16, total_length, pc, & fields->f_cc);
+ break;
+ case FR30_OPERAND_CCC :
+ length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
break;
default :
case FR30_OPERAND_RJ :
print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Rj, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
+ case FR30_OPERAND_RIC :
+ print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Ric, 0|(1<<CGEN_OPERAND_UNSIGNED));
+ break;
+ case FR30_OPERAND_RJC :
+ print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Rjc, 0|(1<<CGEN_OPERAND_UNSIGNED));
+ break;
+ case FR30_OPERAND_CRI :
+ print_keyword (od, info, & fr30_cgen_opval_h_cr, fields->f_CRi, 0|(1<<CGEN_OPERAND_UNSIGNED));
+ break;
+ case FR30_OPERAND_CRJ :
+ print_keyword (od, info, & fr30_cgen_opval_h_cr, fields->f_CRj, 0|(1<<CGEN_OPERAND_UNSIGNED));
+ break;
case FR30_OPERAND_RS1 :
print_keyword (od, info, & fr30_cgen_opval_h_dr, fields->f_Rs1, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case FR30_OPERAND_U4 :
print_normal (od, info, fields->f_u4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
- case FR30_OPERAND_M4 :
- print_normal (od, info, fields->f_m4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
+ case FR30_OPERAND_U4C :
+ print_normal (od, info, fields->f_u4c, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_U8 :
print_normal (od, info, fields->f_u8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
print_normal (od, info, fields->f_udisp6, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_DISP8 :
- print_normal (od, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
+ print_normal (od, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case FR30_OPERAND_DISP9 :
- print_normal (od, info, fields->f_disp9, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
+ print_normal (od, info, fields->f_disp9, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case FR30_OPERAND_DISP10 :
- print_normal (od, info, fields->f_disp10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
+ print_normal (od, info, fields->f_disp10, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case FR30_OPERAND_S10 :
- print_normal (od, info, fields->f_s10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
+ print_normal (od, info, fields->f_s10, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case FR30_OPERAND_U10 :
print_normal (od, info, fields->f_u10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
case FR30_OPERAND_I32 :
print_normal (od, info, fields->f_i32, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
+ case FR30_OPERAND_M4 :
+ print_m4 (od, info, fields->f_m4, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
+ break;
+ case FR30_OPERAND_I20 :
+ print_normal (od, info, fields->f_i20, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
+ break;
case FR30_OPERAND_DIR8 :
print_normal (od, info, fields->f_dir8, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
print_normal (od, info, fields->f_dir10, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_LABEL9 :
- print_normal (od, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
+ print_address (od, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case FR30_OPERAND_LABEL12 :
- print_normal (od, info, fields->f_rel12, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
+ print_address (od, info, fields->f_rel12, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
+ break;
+ case FR30_OPERAND_REGLIST_LOW_LD :
+ print_low_register_list_ld (od, info, fields->f_reglist_low_ld, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
+ break;
+ case FR30_OPERAND_REGLIST_HI_LD :
+ print_hi_register_list_ld (od, info, fields->f_reglist_hi_ld, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
+ break;
+ case FR30_OPERAND_REGLIST_LOW_ST :
+ print_low_register_list_st (od, info, fields->f_reglist_low_st, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
+ break;
+ case FR30_OPERAND_REGLIST_HI_ST :
+ print_hi_register_list_st (od, info, fields->f_reglist_hi_st, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_CC :
print_normal (od, info, fields->f_cc, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
+ case FR30_OPERAND_CCC :
+ print_normal (od, info, fields->f_ccc, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
+ break;
default :
/* xgettext:c-format */
/* Subroutine of extract_normal.
Ensure sufficient bytes are cached in EX_INFO.
+ OFFSET is the offset in bytes from the start of the insn of the value.
+ BYTES is the length of the needed value.
Returns 1 for success, 0 for failure. */
static INLINE int
/* Written this way to avoid undefined behaviour. */
mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (CGEN_INSN_LSB0_P)
- shift = start;
+ shift = (start + 1) - length;
else
shift = (word_length - (start + length));
return (x >> shift) & mask;
INSN_VALUE is the first CGEN_BASE_INSN_SIZE bits of the insn in host order,
or sometimes less for cases like the m32r where the base insn size is 32
but some insns are 16 bits.
- ATTRS is a mask of the boolean attributes. We only need `unsigned',
+ ATTRS is a mask of the boolean attributes. We only need `UNSIGNED',
but for generality we take a bitmask of all of them.
- TOTAL_LENGTH is the length of the insn in bits.
+ WORD_OFFSET is the offset in bits from the start of the insn of the value.
+ WORD_LENGTH is the length of the word in bits in which the value resides.
+ START is the starting bit number in the word, architecture origin.
+ LENGTH is the length of VALUE in bits.
+ TOTAL_LENGTH is the total length of the insn in bits.
Returns 1 for success, 0 for failure. */
+/* ??? The return code isn't properly used. wip. */
+
/* ??? This doesn't handle bfd_vma's. Create another function when
necessary. */
static int
-extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, pc, valuep)
+extract_normal (od, ex_info, insn_value, attrs, word_offset, start, length,
+ word_length, total_length, pc, valuep)
CGEN_OPCODE_DESC od;
CGEN_EXTRACT_INFO *ex_info;
CGEN_INSN_INT insn_value;
unsigned int attrs;
- int start, length, total_length;
+ unsigned int word_offset, start, length, word_length, total_length;
bfd_vma pc;
long *valuep;
{
- unsigned long value;
+ CGEN_INSN_INT value;
/* If LENGTH is zero, this operand doesn't contribute to the value
so give it a standard value of zero. */
}
if (CGEN_INT_INSN_P
- || (CGEN_INSN_LSB0_P
- ? ((total_length - start) <= CGEN_BASE_INSN_BITSIZE)
- : ((start + length) <= CGEN_BASE_INSN_BITSIZE)))
+ && word_offset != 0)
+ abort ();
+
+ if (word_length > 32)
+ abort ();
+
+ /* For architectures with insns smaller than the insn-base-bitsize,
+ word_length may be too big. */
+#if CGEN_MIN_INSN_BITSIZE < CGEN_BASE_INSN_BITSIZE
+ if (word_offset == 0
+ && word_length > total_length)
+ word_length = total_length;
+#endif
+
+ /* Does the value reside in INSN_VALUE? */
+
+ if (word_offset == 0)
{
/* Written this way to avoid undefined behaviour. */
- unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
+ CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (CGEN_INSN_LSB0_P)
- value = insn_value >> start;
+ value = insn_value >> ((start + 1) - length);
else
- value = insn_value >> (total_length - (start + length));
+ value = insn_value >> (word_length - (start + length));
value &= mask;
/* sign extend? */
- if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
+ if (! CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED)
&& (value & (1L << (length - 1))))
value |= ~mask;
}
#if ! CGEN_INT_INSN_P
- /* The hard case is probably too slow for the normal cases.
- It's certainly more difficult to understand than the normal case.
- Thus this is split into two. The hard case is defined
- to be when a field straddles a (loosely defined) word boundary
- (??? which may require target specific help to determine). */
-
-#define HARD_CASE_P 0 /* FIXME:wip */
-
- else if (HARD_CASE_P)
- {
- }
-
else
{
- unsigned char *bufp = ex_info->insn_bytes;
- int offset = 0;
+ unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
- if (length > 32)
+ if (word_length > 32)
abort ();
- /* Adjust start,total_length,bufp to point to the pseudo-word that holds
- the value. For example in a 48 bit insn where the value to insert
- (say an immediate value) is the last 16 bits then fetch_length here
- would be 16. To handle a 24 bit insn with an 18 bit immediate,
- extract_1 handles 24 bits. */
-
- if (total_length > 32)
- {
- int needed_width = start % 8 + length;
- int fetch_length = (needed_width <= 8 ? 8
- : needed_width <= 16 ? 16
- : 32);
-
- if (CGEN_INSN_LSB0_P)
- {
- if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
- {
- abort (); /* wip */
- }
- else
- {
- offset = start & ~7;
-
- bufp += offset / 8;
- start -= offset;
- total_length = fetch_length;
- }
- }
- else
- {
- if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
- {
- offset = start & ~7;
-
- bufp += offset / 8;
- start -= offset;
- total_length = fetch_length;
- }
- else
- {
- abort (); /* wip */
- }
- }
- }
-
- if (fill_cache (od, ex_info, offset / 8, total_length / 8, pc) == 0)
+ if (fill_cache (od, ex_info, word_offset / 8, word_length / 8, pc) == 0)
return 0;
- value = extract_1 (od, ex_info, start, length, total_length, bufp, pc);
+ value = extract_1 (od, ex_info, start, length, word_length, bufp, pc);
}
#endif /* ! CGEN_INT_INSN_P */
/* Basic bit mask must be correct. */
/* ??? May wish to allow target to defer this check until the extract
handler. */
- if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
+ if ((insn_value & CGEN_INSN_BASE_MASK (insn))
+ == CGEN_INSN_BASE_VALUE (insn))
{
/* Printing is handled in two passes. The first pass parses the
machine insn and extracts the fields. The second pass prints