2004-11-05 Tomer Levi <Tomer.Levi@nsc.com>

* config/tc-crx.c: Rename argument types.
 	(processing_arg_number): Rename to 'cur_arg_num'.
	(get_number_of_bits): Rename to 'set_operand_size'.
	(get_operandtype): Rename to 'parse_operand', totally rewrite.
	(set_cons_rparams): Rename to 'set_operand', totally rewrite.
	(set_indexmode_parameters): Remove function, integrate its code into 'set_operand'.
	(set_operand_size): Get rid of 'Operand Number' function parameter - use global variable 'cur_arg_num' instead.
	Use a local 'argument' pointer to reference the current argument.
	(parse_operand): Likewise.
	(set_operand): Likewise.
	(process_label_constant): Likewise.
This commit is contained in:
Tomer Levi
2004-11-05 11:02:04 +00:00
parent 42048ee72f
commit 82d6ee2a41

View File

@ -99,7 +99,7 @@ int cst4flag;
/* A copy of the original instruction (used in error messages). */ /* A copy of the original instruction (used in error messages). */
char ins_parse[MAX_INST_LEN]; char ins_parse[MAX_INST_LEN];
/* Holds the current processed argument number. */ /* Holds the current processed argument number. */
int processing_arg_number; int cur_arg_num;
/* Generic assembler global variables which must be defined by all targets. */ /* Generic assembler global variables which must be defined by all targets. */
@ -158,12 +158,12 @@ const relax_typeS md_relax_table[] =
static void reset_vars (char *, ins *); static void reset_vars (char *, ins *);
static reg get_register (char *); static reg get_register (char *);
static copreg get_copregister (char *); static copreg get_copregister (char *);
static void get_number_of_bits (ins *, int); static void set_operand_size (ins *);
static argtype getarg_type (operand_type); static argtype getarg_type (operand_type);
static int getbits (operand_type); static int getbits (operand_type);
static int get_flags (operand_type); static int get_flags (operand_type);
static int get_number_of_operands (void); static int get_number_of_operands (void);
static void get_operandtype (char *, int, ins *); static void parse_operand (char *, ins *);
static int gettrap (char *); static int gettrap (char *);
static void handle_LoadStor (char *); static void handle_LoadStor (char *);
static int get_cinv_parameters (char *); static int get_cinv_parameters (char *);
@ -176,9 +176,8 @@ static void print_constant (int, int, argument *);
static int exponent2scale (int); static int exponent2scale (int);
static void mask_const (unsigned long *, int); static void mask_const (unsigned long *, int);
static void mask_reg (int, unsigned short *); static void mask_reg (int, unsigned short *);
static int process_label_constant (char *, ins *, int); static int process_label_constant (char *, ins *);
static void set_indexmode_parameters (char *, ins *, int); static void set_operand (char *, ins *);
static void set_cons_rparams (char *, ins *, int);
static char * preprocess_reglist (char *, int *); static char * preprocess_reglist (char *, int *);
static int assemble_insn (char *, ins *); static int assemble_insn (char *, ins *);
static void print_insn (ins *); static void print_insn (ins *);
@ -290,8 +289,7 @@ reset_vars (char *op, ins *crx_ins)
{ {
unsigned int i; unsigned int i;
processing_arg_number = relocatable = size_was_set cur_arg_num = relocatable = size_was_set = signflag = cst4flag = 0;
= signflag = cst4flag = 0;
memset (& output_opcode, '\0', sizeof (output_opcode)); memset (& output_opcode, '\0', sizeof (output_opcode));
/* Memset the 'signflag' field in every argument. */ /* Memset the 'signflag' field in every argument. */
@ -673,15 +671,16 @@ md_begin (void)
linkrelax = 1; linkrelax = 1;
} }
/* Get the number of bits corresponding to a constant - /* Set the number of bits corresponding to a constant -
here we check for possible overflow cases. */ here we check for possible overflow cases. */
static void static void
get_number_of_bits (ins * crx_ins, int op_num) set_operand_size (ins * crx_ins)
{ {
int cnt_bits = 0; int cnt_bits = 0;
unsigned long int temp = crx_ins->arg[op_num].constant;
const cst4_entry *cst4_op; const cst4_entry *cst4_op;
argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
unsigned long int temp = cur_arg->constant;
/* If the constant's size was already set - nothing to do. */ /* If the constant's size was already set - nothing to do. */
if (size_was_set) if (size_was_set)
@ -700,7 +699,7 @@ get_number_of_bits (ins * crx_ins, int op_num)
{ {
if (cnt_bits == 16) if (cnt_bits == 16)
{ {
crx_ins->arg[op_num].size = 32; cur_arg->size = 32;
return; return;
} }
} }
@ -710,11 +709,11 @@ get_number_of_bits (ins * crx_ins, int op_num)
|| IS_INSN_TYPE (STOR_IMM_INS) || IS_INSN_TYPE (STOR_IMM_INS)
|| IS_INSN_TYPE (CSTBIT_INS)) || IS_INSN_TYPE (CSTBIT_INS))
{ {
if (!signflag && crx_ins->arg[op_num].type == arg_icr) if (!signflag && cur_arg->type == arg_idxr)
{ {
if (cnt_bits == 6) if (cnt_bits == 6)
{ {
crx_ins->arg[op_num].size = 22; cur_arg->size = 22;
return; return;
} }
if (cnt_bits == 22) if (cnt_bits == 22)
@ -725,11 +724,11 @@ get_number_of_bits (ins * crx_ins, int op_num)
16-bit positive signed immediate -->> represent as 32-bit. */ 16-bit positive signed immediate -->> represent as 32-bit. */
if (IS_INSN_TYPE (LD_STOR_INS)) if (IS_INSN_TYPE (LD_STOR_INS))
{ {
if (!signflag && crx_ins->arg[op_num].type == arg_cr) if (!signflag && cur_arg->type == arg_cr)
{ {
if (cnt_bits == 16) if (cnt_bits == 16)
{ {
crx_ins->arg[op_num].size = 32; cur_arg->size = 32;
return; return;
} }
if (cnt_bits == 32) if (cnt_bits == 32)
@ -742,11 +741,11 @@ get_number_of_bits (ins * crx_ins, int op_num)
|| IS_INSN_TYPE (LD_STOR_INS_INC) || IS_INSN_TYPE (LD_STOR_INS_INC)
|| IS_INSN_TYPE (STOR_IMM_INS)) || IS_INSN_TYPE (STOR_IMM_INS))
{ {
if (!signflag && crx_ins->arg[op_num].type == arg_cr) if (!signflag && cur_arg->type == arg_cr)
{ {
if (cnt_bits == 12) if (cnt_bits == 12)
{ {
crx_ins->arg[op_num].size = 28; cur_arg->size = 28;
if (IS_INSN_TYPE (LD_STOR_INS_INC)) if (IS_INSN_TYPE (LD_STOR_INS_INC))
as_bad (_("Offset out of range in Instruction `%s'"), ins_parse); as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
return; return;
@ -763,15 +762,15 @@ get_number_of_bits (ins * crx_ins, int op_num)
/* Handle negative cst4 mapping for arithmetic/cmp&br operations. */ /* Handle negative cst4 mapping for arithmetic/cmp&br operations. */
if (signflag && !relocatable if (signflag && !relocatable
&& ((IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS)) && ((IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
|| ((IS_INSN_TYPE (CMPBR_INS) && op_num == 0)))) || ((IS_INSN_TYPE (CMPBR_INS) && cur_arg_num == 0))))
{ {
for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++) for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
{ {
if (crx_ins->arg[op_num].constant == (unsigned int)(-cst4_op->value)) if (cur_arg->constant == (unsigned int)(-cst4_op->value))
{ {
crx_ins->arg[op_num].size = 4; cur_arg->size = 4;
crx_ins->arg[op_num].constant = cst4_op->binary; cur_arg->constant = cst4_op->binary;
crx_ins->arg[op_num].signflag = 0; cur_arg->signflag = 0;
return; return;
} }
} }
@ -782,32 +781,32 @@ get_number_of_bits (ins * crx_ins, int op_num)
{ {
if (!relocatable) if (!relocatable)
{ {
if (crx_ins->arg[op_num].constant <= 0xffff) if (cur_arg->constant <= 0xffff)
crx_ins->arg[op_num].size = 16; cur_arg->size = 16;
else else
/* Setting to 18 so that there is no match. */ /* Setting to 18 so that there is no match. */
crx_ins->arg[op_num].size = 18; cur_arg->size = 18;
} }
else else
crx_ins->arg[op_num].size = 16; cur_arg->size = 16;
return; return;
} }
if (signflag && IS_INSN_TYPE (ARITH_INS)) if (signflag && IS_INSN_TYPE (ARITH_INS))
{ {
/* For all immediates which can be expressed in less than 16 bits. */ /* For all immediates which can be expressed in less than 16 bits. */
if (crx_ins->arg[op_num].constant <= 0xffff && !relocatable) if (cur_arg->constant <= 0xffff && !relocatable)
{ {
crx_ins->arg[op_num].size = 16; cur_arg->size = 16;
return; return;
} }
/* Either it is relocatable or not representable in 16 bits. */ /* Either it is relocatable or not representable in 16 bits. */
if (crx_ins->arg[op_num].constant < 0xffffffff || relocatable) if (cur_arg->constant < 0xffffffff || relocatable)
{ {
crx_ins->arg[op_num].size = 32; cur_arg->size = 32;
return; return;
} }
crx_ins->arg[op_num].size = 33; cur_arg->size = 33;
return; return;
} }
@ -815,7 +814,7 @@ get_number_of_bits (ins * crx_ins, int op_num)
return; return;
if (!relocatable) if (!relocatable)
crx_ins->arg[op_num].size = cnt_bits; cur_arg->size = cnt_bits;
/* Checking for Error Conditions. */ /* Checking for Error Conditions. */
if (IS_INSN_TYPE (ARITH_INS) && !signflag) if (IS_INSN_TYPE (ARITH_INS) && !signflag)
@ -832,17 +831,19 @@ get_number_of_bits (ins * crx_ins, int op_num)
} }
} }
/* Handle the constants -immediate/absolute values and /* Handle the constants immediate/absolute values and
Labels (jump targets/Memory locations). */ Labels (jump targets/Memory locations). */
static int static int
process_label_constant (char *str, ins * crx_ins, int number) process_label_constant (char *str, ins * crx_ins)
{ {
char *save; char *save;
unsigned long int temp, cnt; unsigned long int temp, cnt;
const cst4_entry *cst4_op; const cst4_entry *cst4_op;
int is_cst4=0; int is_cst4 = 0;
int constant_val = 0; int constant_val = 0;
argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
save = input_line_pointer; save = input_line_pointer;
signflag = 0; signflag = 0;
@ -872,10 +873,9 @@ process_label_constant (char *str, ins * crx_ins, int number)
break; break;
case O_constant: case O_constant:
crx_ins->arg[number].constant = crx_ins->exp.X_add_number; cur_arg->constant = constant_val = crx_ins->exp.X_add_number;
constant_val = crx_ins->exp.X_add_number;
if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS)) if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
&& number == 2) && cur_arg_num == 2)
{ {
LONGLONG temp64 = 0; LONGLONG temp64 = 0;
char ptr; char ptr;
@ -911,10 +911,10 @@ process_label_constant (char *str, ins * crx_ins, int number)
BR_SIZE = 24; BR_SIZE = 24;
} }
jump_value = jump_value >> 1; jump_value = jump_value >> 1;
crx_ins->arg[number].constant = jump_value & BR_MASK; cur_arg->constant = jump_value & BR_MASK;
crx_ins->arg[number].size = BR_SIZE; cur_arg->size = BR_SIZE;
size_was_set = 1; size_was_set = 1;
crx_ins->arg[number].signflag = signflag; cur_arg->signflag = signflag;
input_line_pointer = save; input_line_pointer = save;
return crx_ins->exp.X_op; return crx_ins->exp.X_op;
} }
@ -963,10 +963,10 @@ process_label_constant (char *str, ins * crx_ins, int number)
BR_SIZE = 32; BR_SIZE = 32;
} }
jump_value = jump_value >> 1; jump_value = jump_value >> 1;
crx_ins->arg[number].constant = jump_value & BR_MASK; cur_arg->constant = jump_value & BR_MASK;
crx_ins->arg[number].size = BR_SIZE; cur_arg->size = BR_SIZE;
size_was_set = 1; size_was_set = 1;
crx_ins->arg[number].signflag = signflag; cur_arg->signflag = signflag;
input_line_pointer = save; input_line_pointer = save;
return crx_ins->exp.X_op; return crx_ins->exp.X_op;
} }
@ -976,8 +976,7 @@ process_label_constant (char *str, ins * crx_ins, int number)
&& !IS_INSN_TYPE (CSTBIT_INS) && !IS_INSN_TYPE (STOR_IMM_INS) && !IS_INSN_TYPE (CSTBIT_INS) && !IS_INSN_TYPE (STOR_IMM_INS)
&& !IS_INSN_TYPE (BRANCH_INS) && !IS_INSN_MNEMONIC ("bal")) && !IS_INSN_TYPE (BRANCH_INS) && !IS_INSN_MNEMONIC ("bal"))
{ {
crx_ins->arg[number].constant = cur_arg->constant = ~(cur_arg->constant) + 1;
~(crx_ins->arg[number].constant) + 1;
signflag = 1; signflag = 1;
} }
/* For load/store instruction when the value is in the offset part. */ /* For load/store instruction when the value is in the offset part. */
@ -985,11 +984,9 @@ process_label_constant (char *str, ins * crx_ins, int number)
&& (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (LD_STOR_INS_INC) && (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (LD_STOR_INS_INC)
|| IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS))) || IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS)))
{ {
if (crx_ins->arg[number].type == arg_cr if (cur_arg->type == arg_cr || cur_arg->type == arg_idxr)
|| crx_ins->arg[number].type == arg_icr)
{ {
crx_ins->arg[number].constant = cur_arg->constant = ~(cur_arg->constant) + 1;
~(crx_ins->arg[number].constant) + 1;
signflag = 1; signflag = 1;
} }
} }
@ -997,8 +994,7 @@ process_label_constant (char *str, ins * crx_ins, int number)
{ {
/* Signflag in never set in case of load store instructions /* Signflag in never set in case of load store instructions
Mapping in case of only the arithinsn case. */ Mapping in case of only the arithinsn case. */
if ((crx_ins->arg[number].constant != 1 if ((cur_arg->constant != 1 && cur_arg->constant != 4)
&& crx_ins->arg[number].constant != 4)
|| (!IS_INSN_TYPE (ARITH_INS) || (!IS_INSN_TYPE (ARITH_INS)
&& !IS_INSN_TYPE (ARITH_BYTE_INS) && !IS_INSN_TYPE (ARITH_BYTE_INS)
&& !IS_INSN_TYPE (CMPBR_INS))) && !IS_INSN_TYPE (CMPBR_INS)))
@ -1006,15 +1002,14 @@ process_label_constant (char *str, ins * crx_ins, int number)
/* Counting the number of bits required to represent /* Counting the number of bits required to represent
the constant. */ the constant. */
cnt = 0; cnt = 0;
temp = crx_ins->arg[number].constant - 1; temp = cur_arg->constant - 1;
while (temp > 0) while (temp > 0)
{ {
temp >>= 1; temp >>= 1;
cnt++; cnt++;
} }
crx_ins->arg[number].size = cnt + 1; cur_arg->size = cnt + 1;
crx_ins->arg[number].constant = cur_arg->constant = ~(cur_arg->constant) + 1;
~(crx_ins->arg[number].constant) + 1;
if (IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS)) if (IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
{ {
char ptr; char ptr;
@ -1022,14 +1017,14 @@ process_label_constant (char *str, ins * crx_ins, int number)
temp64 = strtoull (str, (char **) &ptr, 0); temp64 = strtoull (str, (char **) &ptr, 0);
if (cnt < 4) if (cnt < 4)
crx_ins->arg[number].size = 5; cur_arg->size = 5;
if (IS_INSN_TYPE (ARITH_INS)) if (IS_INSN_TYPE (ARITH_INS))
{ {
if (crx_ins->arg[number].size > 32 if (cur_arg->size > 32
|| (temp64 > ULONG_MAX)) || (temp64 > ULONG_MAX))
{ {
if (crx_ins->arg[number].size > 32) if (cur_arg->size > 32)
as_bad (_("In Instruction `%s': Immediate size is \ as_bad (_("In Instruction `%s': Immediate size is \
%lu bits cannot be accomodated"), %lu bits cannot be accomodated"),
ins_parse, cnt + 1); ins_parse, cnt + 1);
@ -1041,11 +1036,11 @@ process_label_constant (char *str, ins * crx_ins, int number)
} }
if (IS_INSN_TYPE (ARITH_BYTE_INS)) if (IS_INSN_TYPE (ARITH_BYTE_INS))
{ {
if (crx_ins->arg[number].size > 16 if (cur_arg->size > 16
|| !((temp64 & 0xFFFF0000) == 0xFFFF0000 || !((temp64 & 0xFFFF0000) == 0xFFFF0000
|| (temp64 & 0xFFFF0000) == 0x0)) || (temp64 & 0xFFFF0000) == 0x0))
{ {
if (crx_ins->arg[number].size > 16) if (cur_arg->size > 16)
as_bad (_("In Instruction `%s': Immediate size is \ as_bad (_("In Instruction `%s': Immediate size is \
%lu bits cannot be accomodated"), %lu bits cannot be accomodated"),
ins_parse, cnt + 1); ins_parse, cnt + 1);
@ -1057,26 +1052,24 @@ process_label_constant (char *str, ins * crx_ins, int number)
} }
} }
} }
if (IS_INSN_TYPE (LD_STOR_INS) && crx_ins->arg[number].type == arg_cr) if (IS_INSN_TYPE (LD_STOR_INS) && cur_arg->type == arg_cr)
{ {
/* Cases handled --- /* Cases handled ---
dispub4/dispuw4/dispud4 and for load store dispubwd4 dispub4/dispuw4/dispud4 and for load store dispubwd4
is applicable only. */ is applicable only. */
if (crx_ins->arg[number].size <= 4) if (cur_arg->size <= 4)
crx_ins->arg[number].size = 5; cur_arg->size = 5;
} }
/* Argument number is checked to distinguish between /* Argument number is checked to distinguish between
immediate and displacement in cmpbranch and bcopcond. */ immediate and displacement in cmpbranch and bcopcond. */
if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS)) if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
&& number == 2) && cur_arg_num == 2)
{ {
if (crx_ins->arg[number].size != 32) if (cur_arg->size != 32)
crx_ins->arg[number].constant = cur_arg->constant >>= 1;
crx_ins->arg[number].constant >> 1;
} }
mask_const (&crx_ins->arg[number].constant, mask_const (&cur_arg->constant, (int) cur_arg->size);
(int) crx_ins->arg[number].size);
} }
} }
else else
@ -1084,42 +1077,40 @@ process_label_constant (char *str, ins * crx_ins, int number)
/* Argument number is checked to distinguish between /* Argument number is checked to distinguish between
immediate and displacement in cmpbranch and bcopcond. */ immediate and displacement in cmpbranch and bcopcond. */
if (((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS)) if (((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
&& number == 2) && cur_arg_num == 2)
|| IS_INSN_TYPE (BRANCH_NEQ_INS)) || IS_INSN_TYPE (BRANCH_NEQ_INS))
{ {
if (IS_INSN_TYPE (BRANCH_NEQ_INS)) if (IS_INSN_TYPE (BRANCH_NEQ_INS))
{ {
if (crx_ins->arg[number].constant == 0) if (cur_arg->constant == 0)
as_bad (_("Instruction `%s' has Zero offset"), ins_parse); as_bad (_("Instruction `%s' has Zero offset"), ins_parse);
} }
if (crx_ins->arg[number].constant % 2 != 0) if (cur_arg->constant % 2 != 0)
as_bad (_("Instruction `%s' has odd offset"), ins_parse); as_bad (_("Instruction `%s' has odd offset"), ins_parse);
if (IS_INSN_TYPE (BRANCH_NEQ_INS)) if (IS_INSN_TYPE (BRANCH_NEQ_INS))
{ {
if (crx_ins->arg[number].constant > 32 if (cur_arg->constant > 32 || cur_arg->constant < 2)
|| crx_ins->arg[number].constant < 2)
as_bad (_("Instruction `%s' has illegal offset (%ld)"), as_bad (_("Instruction `%s' has illegal offset (%ld)"),
ins_parse, crx_ins->arg[number].constant); ins_parse, cur_arg->constant);
crx_ins->arg[number].constant -= 2; cur_arg->constant -= 2;
} }
crx_ins->arg[number].constant = cur_arg->constant >>= 1;
crx_ins->arg[number].constant >> 1; set_operand_size (crx_ins);
get_number_of_bits (crx_ins, number);
} }
/* Compare branch argument number zero to be compared - /* Compare branch argument number zero to be compared -
mapped to cst4. */ mapped to cst4. */
if (IS_INSN_TYPE (CMPBR_INS) && number == 0) if (IS_INSN_TYPE (CMPBR_INS) && cur_arg_num == 0)
{ {
for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++) for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
{ {
if (crx_ins->arg[number].constant == (unsigned int)cst4_op->value) if (cur_arg->constant == (unsigned int)cst4_op->value)
{ {
crx_ins->arg[number].constant = cst4_op->binary; cur_arg->constant = cst4_op->binary;
is_cst4 = 1; is_cst4 = 1;
break; break;
} }
@ -1133,11 +1124,10 @@ process_label_constant (char *str, ins * crx_ins, int number)
case O_symbol: case O_symbol:
case O_subtract: case O_subtract:
crx_ins->arg[number].constant = 0;
crx_ins->rtype = BFD_RELOC_NONE; crx_ins->rtype = BFD_RELOC_NONE;
relocatable = 1; relocatable = 1;
switch (crx_ins->arg[number].type) switch (cur_arg->type)
{ {
case arg_cr: case arg_cr:
/* Have to consider various cases here. */ /* Have to consider various cases here. */
@ -1152,7 +1142,7 @@ process_label_constant (char *str, ins * crx_ins, int number)
/* General load/stor instruction. */ /* General load/stor instruction. */
crx_ins->rtype = BFD_RELOC_CRX_REGREL32; crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
break; break;
case arg_icr: case arg_idxr:
/* Index Mode 22 bits relocation. */ /* Index Mode 22 bits relocation. */
crx_ins->rtype = BFD_RELOC_CRX_REGREL22; crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
break; break;
@ -1173,7 +1163,6 @@ process_label_constant (char *str, ins * crx_ins, int number)
crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP; crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
break; break;
case arg_ic: case arg_ic:
case arg_dc:
if (IS_INSN_TYPE (ARITH_INS)) if (IS_INSN_TYPE (ARITH_INS))
crx_ins->rtype = BFD_RELOC_CRX_IMM32; crx_ins->rtype = BFD_RELOC_CRX_IMM32;
else if (IS_INSN_TYPE (ARITH_BYTE_INS)) else if (IS_INSN_TYPE (ARITH_BYTE_INS))
@ -1182,7 +1171,7 @@ process_label_constant (char *str, ins * crx_ins, int number)
default: default:
break; break;
} }
crx_ins->arg[number].size = (bfd_reloc_type_lookup (stdoutput, crx_ins->rtype))->bitsize; cur_arg->size = (bfd_reloc_type_lookup (stdoutput, crx_ins->rtype))->bitsize;
break; break;
default: default:
@ -1190,7 +1179,7 @@ process_label_constant (char *str, ins * crx_ins, int number)
} }
input_line_pointer = save; input_line_pointer = save;
crx_ins->arg[number].signflag = signflag; cur_arg->signflag = signflag;
return crx_ins->exp.X_op; return crx_ins->exp.X_op;
} }
@ -1212,301 +1201,232 @@ exponent2scale (int val)
return exponent; return exponent;
} }
/* This is used to set the index mode parameters. Used to set the attributes of /* Parsing different types of operands
an indexmode type of operand. op_num is the operand number. */ -> constants Immediate/Absolute/Relative numbers
-> Labels Relocatable symbols
-> (rbase) Register base
-> disp(rbase) Register relative
-> disp(rbase)+ Post-increment mode
-> disp(rbase,ridx,scl) Register index mode */
static void static void
set_indexmode_parameters (char *operand, ins * crx_ins, int op_num) set_operand (char *operand, ins * crx_ins)
{ {
char address_str[30]; char *operandS; /* Pointer to start of sub-opearand. */
char scale_str[MAX_OPERANDS]; char *operandE; /* Pointer to end of sub-opearand. */
int scale_cnt = 0; expressionS scale;
char reg_name[MAX_REGNAME_LEN]; int scale_val;
char regindex_name[MAX_REGNAME_LEN]; char *input_save, c;
int i = 0; argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
int reg_counter = 0, addr_cnt = 0, temp_int_val = 0;
switch (crx_ins->arg[op_num].type) /* Initialize pointers. */
operandS = operandE = operand;
switch (cur_arg->type)
{ {
case arg_icr: case arg_sc: /* Case *+0x18. */
while (operand[i] != '(') case arg_ic: /* Case $0x18. */
{ operandS++;
address_str[addr_cnt++] = operand[i]; case arg_c: /* Case 0x18. */
i++; /* Set constant. */
} process_label_constant (operandS, crx_ins/*, op_num*/);
address_str[addr_cnt] = '\0';
process_label_constant (address_str, crx_ins, op_num); if (cur_arg->type != arg_ic)
i++; cur_arg->type = arg_c;
reg_counter = 0; break;
while (operand[i] != ',' && operand[i] != ' ')
{ case arg_icr: /* Case $0x18(r1). */
reg_name[reg_counter++] = operand[i]; operandS++;
i++; case arg_cr: /* Case 0x18(r1). */
} /* Set displacement constant. */
reg_name[reg_counter] = '\0'; while (*operandE != '(')
if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister) operandE++;
*operandE = '\0';
process_label_constant (operandS, crx_ins/*, op_num*/);
operandS = operandE;
case arg_rbase: /* Case (r1). */
operandS++;
/* Set register base. */
while (*operandE != ')')
operandE++;
*operandE = '\0';
if ((cur_arg->r = get_register (operandS)) == nullregister)
as_bad (_("Illegal register `%s' in Instruction `%s'"), as_bad (_("Illegal register `%s' in Instruction `%s'"),
reg_name, ins_parse); operandS, ins_parse);
i++; if (cur_arg->type != arg_rbase)
while (operand[i] == ' ') cur_arg->type = arg_cr;
i++; break;
reg_counter = 0; case arg_idxr:
while (operand[i] != ')' && operand[i] != ',') /* Set displacement constant. */
{ while (*operandE != '(')
regindex_name[reg_counter++] = operand[i]; operandE++;
i++; *operandE = '\0';
} process_label_constant (operandS, crx_ins);
regindex_name[reg_counter] = '\0'; operandS = ++operandE;
reg_counter = 0;
if ((crx_ins->arg[op_num].i_r = get_register (regindex_name)) /* Set register base. */
== nullregister) while ((*operandE != ',') && (! ISSPACE (*operandE)))
operandE++;
*operandE++ = '\0';
if ((cur_arg->r = get_register (operandS)) == nullregister)
as_bad (_("Illegal register `%s' in Instruction `%s'"), as_bad (_("Illegal register `%s' in Instruction `%s'"),
regindex_name, ins_parse); operandS, ins_parse);
/* Setting the scale parameters. */ /* Skip leading white space. */
while (operand[i] == ' ') while (ISSPACE (*operandE))
i++; operandE++;
operandS = operandE;
if (operand[i] == ')') /* Set register index. */
crx_ins->arg[op_num].scale = 0; while ((*operandE != ')') && (*operandE != ','))
operandE++;
c = *operandE;
*operandE++ = '\0';
if ((cur_arg->i_r = get_register (operandS)) == nullregister)
as_bad (_("Illegal register `%s' in Instruction `%s'"),
operandS, ins_parse);
/* Skip leading white space. */
while (ISSPACE (*operandE))
operandE++;
operandS = operandE;
/* Set the scale. */
if (c == ')')
cur_arg->scale = 0;
else else
{ {
if (operand[i] == ',') while (*operandE != ')')
i++; operandE++;
*operandE = '\0';
while (operand[i] != ' ' && operand[i] != ')') /* Preprocess the scale string. */
{ input_save = input_line_pointer;
scale_str[scale_cnt++] = operand[i]; input_line_pointer = operandS;
i++; expression (&scale);
} input_line_pointer = input_save;
scale_str[scale_cnt] = '\0'; scale_val = scale.X_add_number;
/* Preprocess the scale string. */
if (strstr (scale_str, "0x") != NULL
|| strstr (scale_str, "0X") != NULL)
{
sscanf (scale_str, "%x", &temp_int_val);
memset (&scale_str, '\0', sizeof (scale_str));
sprintf (scale_str, "%d", temp_int_val);
}
/* Preprocess over. */
temp_int_val = atoi (scale_str);
if (temp_int_val != 1 && temp_int_val != 2 /* Check if the scale value is legal. */
&& temp_int_val != 4 && temp_int_val != 8) if (scale_val != 1 && scale_val != 2
as_bad (_("Illegal Scale - `%s'"), scale_str); && scale_val != 4 && scale_val != 8)
as_bad (_("Illegal Scale - `%d'"), scale_val);
crx_ins->arg[op_num].scale = exponent2scale (temp_int_val); cur_arg->scale = exponent2scale (scale_val);
} }
break; break;
default: default:
break; break;
} }
} }
/* Parsing the operands of types /* Parse a single operand.
- constants operand - Current operand to parse.
- (rbase) crx_ins - Current assembled instruction. */
- offset(rbase)
- offset(rbase)+ (post-increment mode). */
static void static void
set_cons_rparams (char *operand, ins * crx_ins, int op_num) parse_operand (char *operand, ins * crx_ins)
{
int i = 0, reg_count = 0;
char reg_name[MAX_REGNAME_LEN];
int change_flag = 0;
if (crx_ins->arg[op_num].type == arg_dc)
change_flag = 1;
switch (crx_ins->arg[op_num].type)
{
case arg_sc: /* Case *+347. */
case arg_dc: /* Case $18. */
i++;
case arg_c:/* Case where its a simple constant. */
process_label_constant (operand + i, crx_ins, op_num);
crx_ins->arg[op_num].type = arg_c;
break;
case arg_dcr: /* Case $9(r13). */
operand++;
case arg_cr: /* Case 9(r13. */
while (operand[i] != '(')
i++;
operand[i] = '\0';
process_label_constant (operand, crx_ins, op_num);
operand[i] = '(';
case arg_rbase:
i++;
reg_count = 0;
while (operand[i] != ')')
{
reg_name[reg_count] = operand[i];
i++;
reg_count++;
}
reg_name[reg_count] = '\0';
if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister)
as_bad (_("Illegal register `%s' in Instruction `%s'"),
reg_name, ins_parse);
if (crx_ins->arg[op_num].type != arg_rbase)
crx_ins->arg[op_num].type = arg_cr;
break;
default:
break;
}
if (change_flag == 1)
crx_ins->arg[op_num].type = arg_ic;
}
/* This is used to get the operand attributes -
operand - current operand to be used
number - operand number
crx_ins - current assembled instruction. */
static void
get_operandtype (char *operand, int number, ins * crx_ins)
{ {
int ret_val; int ret_val;
argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
/* Initialize the type to NULL before parsing. */
cur_arg->type = nullargs;
/* Check whether this is a general processor register. */
if ((ret_val = get_register (operand)) != nullregister)
{
cur_arg->type = arg_r;
cur_arg->r = ret_val;
goto set_size;
}
/* Check whether this is a core [special] coprocessor register. */
if ((ret_val = get_copregister (operand)) != nullcopregister)
{
cur_arg->type = arg_copr;
if (ret_val >= cs0)
cur_arg->type = arg_copsr;
cur_arg->cr = ret_val;
goto set_size;
}
/* Deal with special characters. */
switch (operand[0]) switch (operand[0])
{ {
/* When it is a register. */
case 'r':
case 'c':
case 'i':
case 'u':
case 's':
case 'p':
case 'l':
case 'h':
/* Check whether this is a general processor register. */
ret_val = get_register (operand);
if (ret_val != nullregister)
{
crx_ins->arg[number].type = arg_r;
crx_ins->arg[number].r = ret_val;
crx_ins->arg[number].size = REG_SIZE;
}
else
{
/* Check whether this is a core [special] coprocessor register. */
ret_val = get_copregister (operand);
if (ret_val != nullcopregister)
{
crx_ins->arg[number].type = arg_copr;
if (ret_val >= cs0)
crx_ins->arg[number].type = arg_copsr;
crx_ins->arg[number].cr = ret_val;
crx_ins->arg[number].size = REG_SIZE;
}
else
{
if (strchr (operand, '(') != NULL)
{
if (strchr (operand, ',') != NULL
&& (strchr (operand, ',') > strchr (operand, '(')))
{
crx_ins->arg[number].type = arg_icr;
crx_ins->arg[number].constant = 0;
set_indexmode_parameters (operand, crx_ins, number);
get_number_of_bits (crx_ins, number);
return;
}
else
crx_ins->arg[number].type = arg_cr;
}
else
crx_ins->arg[number].type = arg_c;
crx_ins->arg[number].constant = 0;
set_cons_rparams (operand, crx_ins, number);
get_number_of_bits (crx_ins, number);
}
}
break;
case '$': case '$':
if (strchr (operand, '(') != NULL) if (strchr (operand, '(') != NULL)
crx_ins->arg[number].type = arg_dcr; cur_arg->type = arg_icr;
else else
crx_ins->arg[number].type = arg_dc; cur_arg->type = arg_ic;
crx_ins->arg[number].constant = 0; goto set_params;
set_cons_rparams (operand, crx_ins, number); break;
get_number_of_bits (crx_ins, number);
case '*':
cur_arg->type = arg_sc;
goto set_params;
break; break;
case '(': case '(':
crx_ins->arg[number].type = arg_rbase; cur_arg->type = arg_rbase;
set_cons_rparams (operand, crx_ins, number); goto set_params;
crx_ins->arg[number].size = REG_SIZE;
break;
case '*':
crx_ins->arg[number].type = arg_sc;
crx_ins->arg[number].constant = 0;
set_cons_rparams (operand, crx_ins, number);
get_number_of_bits (crx_ins, number);
break;
case '+':
case '-':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (strchr (operand, '(') != NULL)
{
if (strchr (operand, ',') != NULL
&& (strchr (operand, ',') > strchr (operand, '(')))
{
crx_ins->arg[number].type = arg_icr;
crx_ins->arg[number].constant = 0;
set_indexmode_parameters (operand, crx_ins, number);
get_number_of_bits (crx_ins, number);
return;
}
else
crx_ins->arg[number].type = arg_cr;
}
else
crx_ins->arg[number].type = arg_c;
crx_ins->arg[number].constant = 0;
set_cons_rparams (operand, crx_ins, number);
get_number_of_bits (crx_ins, number);
break; break;
default: default:
if (strchr (operand, '(') != NULL) break;
{ }
if (strchr (operand, ',') != NULL
&& (strchr (operand, ',') > strchr (operand, '('))) if (strchr (operand, '(') != NULL)
{ {
crx_ins->arg[number].type = arg_icr; if (strchr (operand, ',') != NULL
crx_ins->arg[number].constant = 0; && (strchr (operand, ',') > strchr (operand, '(')))
set_indexmode_parameters (operand, crx_ins, number); cur_arg->type = arg_idxr;
get_number_of_bits (crx_ins, number);
return;
}
else
crx_ins->arg[number].type = arg_cr;
}
else else
crx_ins->arg[number].type = arg_c; cur_arg->type = arg_cr;
crx_ins->arg[number].constant = 0; }
set_cons_rparams (operand, crx_ins, number); else
get_number_of_bits (crx_ins, number); cur_arg->type = arg_c;
goto set_params;
/* Parse an operand according to its type. */
set_params:
cur_arg->constant = 0;
set_operand (operand, crx_ins);
/* Determine argument size. */
set_size:
switch (cur_arg->type)
{
/* The following are all registers, so set their size to REG_SIZE. */
case arg_r:
case arg_copr:
case arg_copsr:
case arg_rbase:
cur_arg->size = REG_SIZE;
break;
case arg_c:
case arg_ic:
case arg_sc:
case arg_cr:
case arg_icr:
case arg_idxr:
set_operand_size (crx_ins);
break;
default:
as_bad (_("Illegal argument type in instruction `%s'"), ins_parse);
break; break;
} }
} }
/* Operands are parsed over here, separated into various operands. Each operand /* Parse the various operands. Each operand is then analyzed to fillup
is then analyzed to fillup the fields in the crx_ins data structure. */ the fields in the crx_ins data structure. */
static void static void
parse_operands (ins * crx_ins, char *operands) parse_operands (ins * crx_ins, char *operands)
@ -1572,10 +1492,11 @@ parse_operands (ins * crx_ins, char *operands)
if (bracket_flag || sq_bracket_flag) if (bracket_flag || sq_bracket_flag)
as_fatal (_("Missing matching brackets : `%s'"), ins_parse); as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
/* Now to recongnize the operand types. */ /* Now we parse each operand separately. */
for (op_num = 0; op_num < crx_ins->nargs; op_num++) for (op_num = 0; op_num < crx_ins->nargs; op_num++)
{ {
get_operandtype (operand[op_num], op_num, crx_ins); cur_arg_num = op_num;
parse_operand (operand[op_num], crx_ins);
free (operand[op_num]); free (operand[op_num]);
} }
@ -1699,8 +1620,8 @@ getreg_image (reg r)
char *reg_name; char *reg_name;
int is_procreg = 0; /* Nonzero means argument should be processor reg. */ int is_procreg = 0; /* Nonzero means argument should be processor reg. */
if (((IS_INSN_MNEMONIC ("mtpr")) && (processing_arg_number == 1)) if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
|| ((IS_INSN_MNEMONIC ("mfpr")) && (processing_arg_number == 0)) ) || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
is_procreg = 1; is_procreg = 1;
/* Check whether the register is in registers table. */ /* Check whether the register is in registers table. */
@ -1884,11 +1805,7 @@ print_operand (int nbits, int shift, argument *arg)
CRX_PRINT (0, getreg_image (arg->cr), shift); CRX_PRINT (0, getreg_image (arg->cr), shift);
break; break;
case arg_ic: case arg_idxr:
print_constant (nbits, shift, arg);
break;
case arg_icr:
/* 16 12 8 6 0 /* 16 12 8 6 0
+--------------------------------+ +--------------------------------+
| r_base | r_idx | scl| disp | | r_base | r_idx | scl| disp |
@ -1896,6 +1813,8 @@ print_operand (int nbits, int shift, argument *arg)
CRX_PRINT (0, getreg_image (arg->r), 12); CRX_PRINT (0, getreg_image (arg->r), 12);
CRX_PRINT (0, getreg_image (arg->i_r), 8); CRX_PRINT (0, getreg_image (arg->i_r), 8);
CRX_PRINT (0, arg->scale, 6); CRX_PRINT (0, arg->scale, 6);
case arg_ic:
case arg_c:
print_constant (nbits, shift, arg); print_constant (nbits, shift, arg);
break; break;
@ -1915,10 +1834,6 @@ print_operand (int nbits, int shift, argument *arg)
CRX_PRINT (0, getreg_image (arg->r), shift); CRX_PRINT (0, getreg_image (arg->r), shift);
break; break;
case arg_c:
print_constant (nbits, shift, arg);
break;
default: default:
break; break;
} }
@ -1961,7 +1876,7 @@ assemble_insn (char *mnemonic, ins *insn)
/* Location (in bits) of each operand in the current instruction. */ /* Location (in bits) of each operand in the current instruction. */
int shift_act[MAX_OPERANDS]; int shift_act[MAX_OPERANDS];
/* Instruction type to match. */ /* Instruction type to match. */
int ins_type; unsigned int ins_type;
int match = 0; int match = 0;
int done_flag = 0; int done_flag = 0;
int dispu4map_type = 0; int dispu4map_type = 0;
@ -2295,7 +2210,7 @@ assemble_insn (char *mnemonic, ins *insn)
{ {
shift_act[i] = instruction->operands[i].shift; shift_act[i] = instruction->operands[i].shift;
signflag = insn->arg[i].signflag; signflag = insn->arg[i].signflag;
processing_arg_number = i; cur_arg_num = i;
print_operand (bits_act[i], shift_act[i], &insn->arg[i]); print_operand (bits_act[i], shift_act[i], &insn->arg[i]);
} }
} }