2002-11-19 Klee Dienes * h8300.h (h8_opcode): Remove 'noperands', 'idx', and 'size' fields. (h8_opcodes). Modify initializer and initializer macros to no longer initialize the removed fields. 2002-11-19 Klee Dienes * config/tc-h8300.c (struct h8_instruction): New type, used to wrap h8_opcodes with length, noperands, idx, and size fields (computed at run-time). (h8_instructions): New variable. (md_begin): Allocate the storage for h8_instructions. Fill h8_instructions with pointers to the appropriate opcode and the correct value for the additional fields. (clever_message): Update to use h8_instructions instead of h8_opcodes. (build_bytes): Ditto. (get_specific): Ditto. (md_assemble): Ditto. Index: gas/config/tc-h8300.c =================================================================== RCS file: /cvs/src/src/gas/config/tc-h8300.c,v retrieving revision 1.23 diff -u -r1.23 tc-h8300.c --- gas/config/tc-h8300.c 5 Sep 2002 00:01:17 -0000 1.23 +++ gas/config/tc-h8300.c 19 Nov 2002 22:13:56 -0000 @@ -53,6 +53,17 @@ int bsize = L_8; /* default branch displacement */ +struct h8_instruction +{ + int length; + int noperands; + int idx; + int size; + const struct h8_opcode *opcode; +}; + +struct h8_instruction *h8_instructions; + void h8300hmode (arg) int arg ATTRIBUTE_UNUSED; @@ -134,7 +145,9 @@ void md_begin () { - struct h8_opcode *opcode; + unsigned int nopcodes; + const struct h8_opcode *p; + struct h8_instruction *pi; char prev_buffer[100]; int idx = 0; @@ -146,22 +159,27 @@ opcode_hash_control = hash_new (); prev_buffer[0] = 0; - for (opcode = h8_opcodes; opcode->name; opcode++) + nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode); + + h8_instructions = (struct h8_instruction *) + xmalloc (nopcodes * sizeof (struct h8_instruction)); + + for (p = h8_opcodes, pi = h8_instructions; p->name; p++, pi++) { /* Strip off any . part when inserting the opcode and only enter unique codes into the hash table. */ - char *src = opcode->name; + char *src = p->name; unsigned int len = strlen (src); char *dst = malloc (len + 1); char *buffer = dst; - opcode->size = 0; + pi->size = 0; while (*src) { if (*src == '.') { src++; - opcode->size = *src; + pi->size = *src; break; } *dst++ = *src++; @@ -169,23 +187,32 @@ *dst++ = 0; if (strcmp (buffer, prev_buffer)) { - hash_insert (opcode_hash_control, buffer, (char *) opcode); + hash_insert (opcode_hash_control, buffer, (char *) pi); strcpy (prev_buffer, buffer); idx++; } - opcode->idx = idx; + pi->idx = idx; /* Find the number of operands. */ - opcode->noperands = 0; - while (opcode->args.nib[opcode->noperands] != E) - opcode->noperands++; + pi->noperands = 0; + while (p->args.nib[pi->noperands] != E) + pi->noperands++; /* Find the length of the opcode in bytes. */ - opcode->length = 0; - while (opcode->data.nib[opcode->length * 2] != E) - opcode->length++; + pi->length = 0; + while (p->data.nib[pi->length * 2] != E) + pi->length++; + + pi->opcode = p; } + /* Add entry for the NULL vector terminator. */ + pi->length = 0; + pi->noperands = 0; + pi->idx = 0; + pi->size = 0; + pi->opcode = p; + linkrelax = 1; } @@ -206,11 +233,11 @@ expressionS exp; }; -static void clever_message PARAMS ((struct h8_opcode *, struct h8_op *)); -static void build_bytes PARAMS ((struct h8_opcode *, struct h8_op *)); +static void clever_message PARAMS ((const struct h8_instruction *, struct h8_op *)); +static void build_bytes PARAMS ((const struct h8_instruction *, struct h8_op *)); static void do_a_fix_imm PARAMS ((int, struct h8_op *, int)); static void check_operand PARAMS ((struct h8_op *, unsigned int, char *)); -static struct h8_opcode * get_specific PARAMS ((struct h8_opcode *, struct h8_op *, int)); +static const struct h8_instruction * get_specific PARAMS ((const struct h8_instruction *, struct h8_op *, int)); static char * get_operands PARAMS ((unsigned, char *, struct h8_op *)); static void get_operand PARAMS ((char **, struct h8_op *, unsigned, int)); static char * skip_colonthing PARAMS ((char *, expressionS *, int *)); @@ -694,32 +721,32 @@ addressing modes, return the opcode which matches the opcodes provided. */ -static struct h8_opcode * -get_specific (opcode, operands, size) - struct h8_opcode *opcode; +static const struct h8_instruction * +get_specific (instruction, operands, size) + const struct h8_instruction *instruction; struct h8_op *operands; int size; { - struct h8_opcode *this_try = opcode; + const struct h8_instruction *this_try = instruction; int found = 0; - int this_index = opcode->idx; + int this_index = instruction->idx; /* There's only one ldm/stm and it's easier to just get out quick for them. */ - if (strcmp (opcode->name, "stm.l") == 0 - || strcmp (opcode->name, "ldm.l") == 0) + if (strcmp (instruction->opcode->name, "stm.l") == 0 + || strcmp (instruction->opcode->name, "ldm.l") == 0) return this_try; - while (this_index == opcode->idx && !found) + while (this_index == instruction->idx && !found) { found = 1; - this_try = opcode++; + this_try = instruction++; if (this_try->noperands == 0) { int this_size; - this_size = this_try->how & SN; + this_size = this_try->opcode->how & SN; if (this_size != size && (this_size != SB || size != SN)) found = 0; } @@ -729,7 +756,7 @@ for (i = 0; i < this_try->noperands && found; i++) { - op_type op = this_try->args.nib[i]; + op_type op = this_try->opcode->args.nib[i]; int x = operands[i].mode; if ((op & (DISP | REG)) == (DISP | REG) @@ -964,12 +991,12 @@ static void build_bytes (this_try, operand) - struct h8_opcode *this_try; + const struct h8_instruction *this_try; struct h8_op *operand; { int i; char *output = frag_more (this_try->length); - op_type *nibble_ptr = this_try->data.nib; + op_type *nibble_ptr = this_try->opcode->data.nib; op_type c; unsigned int nibble_count = 0; int absat = 0; @@ -979,9 +1006,9 @@ char asnibbles[30]; char *p = asnibbles; - if (!(this_try->inbase || Hmode)) + if (!(this_try->opcode->inbase || Hmode)) as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"), - this_try->name); + this_try->opcode->name); while (*nibble_ptr != E) { @@ -1076,15 +1103,15 @@ /* Disgusting. Why, oh why didn't someone ask us for advice on the assembler format. */ - if (strcmp (this_try->name, "stm.l") == 0 - || strcmp (this_try->name, "ldm.l") == 0) + if (strcmp (this_try->opcode->name, "stm.l") == 0 + || strcmp (this_try->opcode->name, "ldm.l") == 0) { int high, low; - high = (operand[this_try->name[0] == 'l' ? 1 : 0].reg >> 8) & 0xf; - low = operand[this_try->name[0] == 'l' ? 1 : 0].reg & 0xf; + high = (operand[this_try->opcode->name[0] == 'l' ? 1 : 0].reg >> 8) & 0xf; + low = operand[this_try->opcode->name[0] == 'l' ? 1 : 0].reg & 0xf; asnibbles[2] = high - low; - asnibbles[7] = (this_try->name[0] == 'l') ? high : low; + asnibbles[7] = (this_try->opcode->name[0] == 'l') ? high : low; } for (i = 0; i < this_try->length; i++) @@ -1092,7 +1119,7 @@ /* Note if this is a movb instruction -- there's a special relaxation which only applies to them. */ - if (strcmp (this_try->name, "mov.b") == 0) + if (strcmp (this_try->opcode->name, "mov.b") == 0) movb = 1; /* Output any fixes. */ @@ -1186,21 +1213,21 @@ detect errors. */ static void -clever_message (opcode, operand) - struct h8_opcode *opcode; +clever_message (instruction, operand) + const struct h8_instruction *instruction; struct h8_op *operand; { /* Find out if there was more than one possible opcode. */ - if ((opcode + 1)->idx != opcode->idx) + if ((instruction + 1)->idx != instruction->idx) { int argn; /* Only one opcode of this flavour, try to guess which operand didn't match. */ - for (argn = 0; argn < opcode->noperands; argn++) + for (argn = 0; argn < instruction->noperands; argn++) { - switch (opcode->args.nib[argn]) + switch (instruction->opcode->args.nib[argn]) { case RD16: if (operand[argn].mode != RD16) @@ -1259,8 +1286,8 @@ char *op_start; char *op_end; struct h8_op operand[2]; - struct h8_opcode *opcode; - struct h8_opcode *prev_opcode; + const struct h8_instruction *instruction; + const struct h8_instruction *prev_instruction; char *dot = 0; char c; @@ -1292,10 +1319,10 @@ *op_end = 0; - opcode = (struct h8_opcode *) hash_find (opcode_hash_control, - op_start); + instruction = (const struct h8_instruction *) + hash_find (opcode_hash_control, op_start); - if (opcode == NULL) + if (instruction == NULL) { as_bad (_("unknown opcode")); return; @@ -1304,9 +1331,9 @@ /* We used to set input_line_pointer to the result of get_operands, but that is wrong. Our caller assumes we don't change it. */ - (void) get_operands (opcode->noperands, op_end, operand); + (void) get_operands (instruction->noperands, op_end, operand); *op_end = c; - prev_opcode = opcode; + prev_instruction = instruction; size = SN; if (dot) @@ -1326,28 +1353,28 @@ break; } } - opcode = get_specific (opcode, operand, size); + instruction = get_specific (instruction, operand, size); - if (opcode == 0) + if (instruction == 0) { /* Couldn't find an opcode which matched the operands. */ char *where = frag_more (2); where[0] = 0x0; where[1] = 0x0; - clever_message (prev_opcode, operand); + clever_message (prev_instruction, operand); return; } - if (opcode->size && dot) + if (instruction->size && dot) { - if (opcode->size != *dot) + if (instruction->size != *dot) { as_warn (_("mismatch between opcode size and operand size")); } } - build_bytes (opcode, operand); + build_bytes (instruction, operand); } #ifndef BFD_ASSEMBLER Index: include/opcode/h8300.h =================================================================== RCS file: /cvs/src/src/include/opcode/h8300.h,v retrieving revision 1.8 diff -u -r1.8 h8300.h --- include/opcode/h8300.h 18 Nov 2002 16:52:44 -0000 1.8 +++ include/opcode/h8300.h 19 Nov 2002 22:14:00 -0000 @@ -151,19 +151,16 @@ char *name; struct arg args; struct code data; - int noperands; - int idx; - int size; }; #ifdef DEFINE_TABLE #define BITOP(code, imm, name, op00, op01,op10,op11, op20,op21,op30)\ -{ code, 1, 2, name, {{imm,RD8,E}}, {{op00, op01, imm, RD8, E, 0, 0, 0, 0}}, 0, 0, 0},\ -{ code, 1, 6, name, {{imm,RDIND,E}},{{op10, op11, B30|RDIND, 0, op00,op01, imm, 0, E}}, 0, 0, 0},\ -{ code, 1, 6, name, {{imm,ABS8DST,E}},{{op20, op21, ABS8DST, IGNORE, op00,op01, imm, 0,E}}, 0, 0, 0}\ -,{ code, 0, 6, name, {{imm,ABS16DST,E}},{{0x6,0xa,0x1,op30,ABS16DST,IGNORE,IGNORE,IGNORE, op00,op01, imm, 0,E}}, 0, 0, 0},\ -{ code, 0, 6, name, {{imm,ABS32DST,E}},{{0x6,0xa,0x3,op30,ABS32DST,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE, op00,op01, imm, 0,E}}, 0, 0, 0} +{ code, 1, 2, name, {{imm,RD8,E}}, {{op00, op01, imm, RD8, E, 0, 0, 0, 0}}},\ +{ code, 1, 6, name, {{imm,RDIND,E}},{{op10, op11, B30|RDIND, 0, op00,op01, imm, 0, E}}},\ +{ code, 1, 6, name, {{imm,ABS8DST,E}},{{op20, op21, ABS8DST, IGNORE, op00,op01, imm, 0,E}}}\ +,{ code, 0, 6, name, {{imm,ABS16DST,E}},{{0x6,0xa,0x1,op30,ABS16DST,IGNORE,IGNORE,IGNORE, op00,op01, imm, 0,E}}},\ +{ code, 0, 6, name, {{imm,ABS32DST,E}},{{0x6,0xa,0x3,op30,ABS32DST,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE, op00,op01, imm, 0,E}}} #define EBITOP(code, imm, name, op00, op01,op10,op11, op20,op21,op30)\ @@ -171,33 +168,33 @@ BITOP(code,RS8, name, op00, op01, op10,op11, op20,op21,op30) #define WTWOP(code,name, op1, op2) \ -{ code, 1, 2, name, {{RS16, RD16, E}}, {{ op1, op2, RS16, RD16, E, 0, 0, 0, 0}}, 0, 0, 0} +{ code, 1, 2, name, {{RS16, RD16, E}}, {{ op1, op2, RS16, RD16, E, 0, 0, 0, 0}}} #define BRANCH(code, name, op) \ -{ code, 1, 4,name,{{DISP8,E,0}}, {{ 0x4, op, DISP8, IGNORE, E, 0, 0, 0, 0}}, 0, 0, 0}, \ -{ code, 0, 6,name,{{DISP16,E,0}}, {{ 0x5, 0x8, op, 0x0, DISP16, IGNORE, IGNORE, IGNORE, E,0}}, 0, 0, 0} +{ code, 1, 4,name,{{DISP8,E,0}}, {{ 0x4, op, DISP8, IGNORE, E, 0, 0, 0, 0}}}, \ +{ code, 0, 6,name,{{DISP16,E,0}}, {{ 0x5, 0x8, op, 0x0, DISP16, IGNORE, IGNORE, IGNORE, E,0}}} #define SOP(code, x,name) \ {code, 1, x, name #define NEW_SOP(code, in,x,name) \ {code, in, x, name -#define EOP ,0,0,0 } +#define EOP } #define TWOOP(code, name, op1, op2,op3) \ -{ code,1, 2,name, {{IMM8, RD8, E}}, {{ op1, RD8, IMM8, IGNORE, E, 0, 0, 0, 0}}, 0, 0, 0},\ -{ code, 1, 2,name, {{RS8, RD8, E}}, {{ op2, op3, RS8, RD8, E, 0, 0, 0, 0}}, 0, 0, 0} +{ code,1, 2,name, {{IMM8, RD8, E}}, {{ op1, RD8, IMM8, IGNORE, E, 0, 0, 0, 0}}},\ +{ code, 1, 2,name, {{RS8, RD8, E}}, {{ op2, op3, RS8, RD8, E, 0, 0, 0, 0}}} #define UNOP(code,name, op1, op2) \ -{ code, 1, 2, name, {{OR8, E, 0}}, {{ op1, op2, 0, OR8, E, 0, 0, 0, 0}}, 0, 0, 0} +{ code, 1, 2, name, {{OR8, E, 0}}, {{ op1, op2, 0, OR8, E, 0, 0, 0, 0}}} #define UNOP3(code, name, op1, op2, op3) \ -{ O(code,SB), 1, 2, name, {{OR8, E, 0}}, {{op1, op2, op3+0, OR8, E, 0, 0, 0, 0}}, 0, 0, 0}, \ -{ O(code,SW), 0, 2, name, {{OR16, E, 0}}, {{op1, op2, op3+1, OR16, E, 0, 0, 0, 0}}, 0, 0, 0}, \ -{ O(code,SL), 0, 2, name, {{OR32, E, 0}}, {{op1, op2, op3+3, OR32|B30, E, 0, 0, 0, 0}}, 0, 0, 0} \ -,{ O(code,SB), 1, 2, name, {{IMM, OR8 | SRC_IN_DST, E}}, {{op1, op2, op3+4, OR8 | SRC_IN_DST, E, 0, 0, 0, 0}}, 0, 0, 0}, \ -{ O(code,SW), 0, 2, name, {{IMM, OR16 | SRC_IN_DST, E}}, {{op1, op2, op3+5, OR16 | SRC_IN_DST, E, 0, 0, 0, 0}}, 0, 0, 0}, \ -{ O(code,SL), 0, 2, name, {{IMM, OR32 | SRC_IN_DST, E}}, {{op1, op2, op3+7, OR32 | SRC_IN_DST|B30 , E, 0, 0, 0, 0}}, 0, 0, 0} +{ O(code,SB), 1, 2, name, {{OR8, E, 0}}, {{op1, op2, op3+0, OR8, E, 0, 0, 0, 0}}}, \ +{ O(code,SW), 0, 2, name, {{OR16, E, 0}}, {{op1, op2, op3+1, OR16, E, 0, 0, 0, 0}}}, \ +{ O(code,SL), 0, 2, name, {{OR32, E, 0}}, {{op1, op2, op3+3, OR32|B30, E, 0, 0, 0, 0}}} \ +,{ O(code,SB), 1, 2, name, {{IMM, OR8 | SRC_IN_DST, E}}, {{op1, op2, op3+4, OR8 | SRC_IN_DST, E, 0, 0, 0, 0}}}, \ +{ O(code,SW), 0, 2, name, {{IMM, OR16 | SRC_IN_DST, E}}, {{op1, op2, op3+5, OR16 | SRC_IN_DST, E, 0, 0, 0, 0}}}, \ +{ O(code,SL), 0, 2, name, {{IMM, OR32 | SRC_IN_DST, E}}, {{op1, op2, op3+7, OR32 | SRC_IN_DST|B30 , E, 0, 0, 0, 0}}} #define IMM32LIST IMM32,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE @@ -593,7 +590,7 @@ NEW_SOP(O(O_STMAC,SL),1,2,"stmac"),{{MACREG,RD32,E}},{{0x0,0x2,MACREG,RD32,E}} EOP, NEW_SOP(O(O_LDM,SL),0,6,"ldm.l"),{{RSINC, RS32, E}},{{ 0x0,0x1,IGNORE,0x0,0x6,0xD,0x7,IGNORE,E}}EOP, NEW_SOP(O(O_STM,SL),0,6,"stm.l"),{{RS32, RDDEC, E}},{{0x0,0x1,IGNORE,0x0,0x6,0xD,0xF,IGNORE,E}}EOP, - {0, 0, 0, NULL, {{0,0,0}}, {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}, 0, 0, 0} + {0, 0, 0, NULL, {{0,0,0}}, {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}} }; #else extern const struct h8_opcode h8_opcodes[];