From mboxrd@z Thu Jan 1 00:00:00 1970 From: Richard Sandiford To: cgen@sources.redhat.com Subject: Patch: make fixups use word_offset Date: Wed, 03 Jan 2001 07:36:00 -0000 Message-id: X-SW-Source: 2001-q1/msg00013.html At the moment, all operand fixups seem to be made from the start of the instruction. It seems likely that, in general, you'd want the fixup address to be the start of word that contains the value. This patches gas_cgen_finish_insn() so that it adds the operand's word_offset/8 to the instruction's address. I had to add the instruction field number to the cgen_operand structure, but I got the impression that the change was already planned. Patches for opcodes, include, gas and cgen (separated out: is that the right thing to do?). Checked on fr30. Please install if OK. -- OPCODES 2001-01-03 Richard Sandiford * cgen-opc.c (cgen_ifield_lookup_by_num): Added. Index: opcodes/cgen-opc.c =================================================================== RCS file: /cvs/src/src/opcodes/cgen-opc.c,v retrieving revision 1.5 diff -c -p -d -r1.5 cgen-opc.c *** cgen-opc.c 2001/01/02 16:34:07 1.5 --- opcodes/cgen-opc.c 2001/01/03 14:06:29 *************** cgen_hw_lookup_by_num (cd, hwnum) *** 298,303 **** --- 298,313 ---- return NULL; } + /* Instruction fields. */ + + const CGEN_IFLD * + cgen_ifield_lookup_by_num (cd, ifnum) + CGEN_CPU_DESC cd; + unsigned int ifnum; + { + return &cd->ifld_table[ifnum]; + } + /* Operand support. */ /* Lookup an operand by its name. -- INCLUDE 2001-01-03 Richard Sandiford * opcode/cgen.h (ifield_type): Define to a dummy value if CGEN_ARCH not defined. (cgen_operand_type): Replace start and length fields with ifield member. Index: include/opcode/cgen.h =================================================================== RCS file: /cvs/src/src/include/opcode/cgen.h,v retrieving revision 1.7 diff -c -p -d -r1.7 cgen.h *** cgen.h 2000/07/26 22:44:42 1.7 --- include/opcode/cgen.h 2001/01/03 14:05:21 *************** enum cgen_asm_type *** 408,413 **** --- 408,414 ---- #ifndef CGEN_ARCH enum cgen_hw_type { CGEN_HW_MAX }; + enum ifield_type { CGEN_IFLD_MAX }; #endif /* List of hardware elements. */ *************** typedef struct *** 614,634 **** /* The hardware element associated with this operand. */ enum cgen_hw_type hw_type; - - /* FIXME: We don't yet record ifield definitions, which we should. - When we do it might make sense to delete start/length (since they will - be duplicated in the ifield's definition) and replace them with a - pointer to the ifield entry. */ - - /* Bit position. - This is just a hint, and may be unused in more complex operands. - May be unused for a modifier. */ - unsigned char start; ! /* The number of bits in the operand. ! This is just a hint, and may be unused in more complex operands. ! May be unused for a modifier. */ ! unsigned char length; #if 0 /* ??? Interesting idea but relocs tend to get too complicated, and ABI dependent, for simple table lookups to work. */ --- 615,623 ---- /* The hardware element associated with this operand. */ enum cgen_hw_type hw_type; ! /* The field that the operand is stored in. */ ! enum ifield_type ifield; #if 0 /* ??? Interesting idea but relocs tend to get too complicated, and ABI dependent, for simple table lookups to work. */ *************** typedef struct cgen_ifld { *** 809,814 **** --- 798,807 ---- /* Return value of attribute ATTR in IFLD. */ #define CGEN_IFLD_ATTR_VALUE(ifld, attr) \ CGEN_ATTR_VALUE ((ifld), CGEN_IFLD_ATTRS (ifld), (attr)) + + extern const CGEN_IFLD * cgen_ifield_lookup_by_num + PARAMS ((CGEN_CPU_DESC, unsigned int)); + /* Instruction data. */ -- GAS 2001-01-03 Richard Sandiford * gas/cgen.c (gas_cgen_finish_insn): Add an operand's word offset to fixup addresses. Index: gas/cgen.c =================================================================== RCS file: /cvs/src/src/gas/cgen.c,v retrieving revision 1.7 diff -c -p -d -r1.7 cgen.c *** cgen.c 2000/10/11 20:24:32 1.7 --- gas/cgen.c 2001/01/03 14:06:50 *************** gas_cgen_finish_insn (insn, buf, length, *** 451,456 **** --- 451,458 ---- fixS *fixP; const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex); + const CGEN_IFLD *field; + int where; /* Don't create fixups for these. That's done during relaxation. We don't need to test for CGEN_INSN_RELAX as they can't get here *************** gas_cgen_finish_insn (insn, buf, length, *** 464,470 **** #define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp #endif ! fixP = md_cgen_record_fixup_exp (frag_now, f - frag_now->fr_literal, insn, length, operand, fixups[i].opinfo, &fixups[i].exp); --- 466,474 ---- #define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp #endif ! field = cgen_ifield_lookup_by_num (gas_cgen_cpu_desc, operand->ifield); ! where = f - frag_now->fr_literal + field->word_offset / 8; ! fixP = md_cgen_record_fixup_exp (frag_now, where, insn, length, operand, fixups[i].opinfo, &fixups[i].exp); -- CGEN 2001-01-03 Richard Sandiford * cgen/desc-cpu.scm (gen-operand-table): Replaced start and length fields with the instruction field number. * cgen/ifield.scm (ifld-enum): Enumerate f-nil as F_NIL (-ifield-parse): Add SIGNED attribute. * cgen/opcodes.scm (gen-insert): Remove special handling of SIGNED attribute. Index: cgen/desc-cpu.scm =================================================================== RCS file: /cvs/src/src/cgen/desc-cpu.scm,v retrieving revision 1.4 diff -c -p -d -r1.4 desc-cpu.scm *** desc-cpu.scm 2000/12/03 04:53:23 1.4 --- cgen/desc-cpu.scm 2001/01/03 14:07:11 *************** const CGEN_OPERAND @arch@_cgen_operand_t *** 405,412 **** "\"" (obj:name op) "\", " (op-enum op) ", " (hw-enum (op:hw-name op)) ", " ! (number->string (op:start op)) ", " ! (number->string (op:length op)) ",\n" " " (gen-obj-attr-defn 'operand op all-attrs num-non-bools gen-A-attr-mask) --- 405,411 ---- "\"" (obj:name op) "\", " (op-enum op) ", " (hw-enum (op:hw-name op)) ", " ! (ifld-enum (op-ifield op)) ",\n" " " (gen-obj-attr-defn 'operand op all-attrs num-non-bools gen-A-attr-mask) Index: cgen/ifield.scm =================================================================== RCS file: /cvs/src/src/cgen/ifield.scm,v retrieving revision 1.3 diff -c -p -d -r1.3 ifield.scm *** ifield.scm 2000/09/15 15:01:20 1.3 --- cgen/ifield.scm 2001/01/03 14:07:13 *************** *** 186,192 **** (string-upcase (string-append (if (or (null? prefix?) (car prefix?)) "@ARCH@_" "") ! (gen-sym ifld))) ) ; Return a boolean indicating if ifield F is an opcode field --- 186,192 ---- (string-upcase (string-append (if (or (null? prefix?) (car prefix?)) "@ARCH@_" "") ! (if ifld (gen-sym ifld) "F_NIL"))) ) ; Return a boolean indicating if ifield F is an opcode field *************** *** 520,526 **** (make name (parse-comment comment errtxt) ! atlist mode-obj bitrange (-ifld-parse-encode errtxt encode) --- 520,528 ---- (make name (parse-comment comment errtxt) ! (if (eq? (mode:class mode-obj) 'INT) ! (atlist-cons (bool-attr-make 'SIGNED #t) atlist) ! atlist) mode-obj bitrange (-ifld-parse-encode errtxt encode) Index: cgen/opcodes.scm =================================================================== RCS file: /cvs/src/src/cgen/opcodes.scm,v retrieving revision 1.1.1.1 diff -c -p -d -r1.1.1.1 opcodes.scm *** opcodes.scm 2000/07/28 04:11:52 1.1.1.1 --- cgen/opcodes.scm 2001/01/03 14:07:14 *************** *** 117,132 **** (if need-extra? "value" varname) - ", " ; We explicitly pass the attributes here rather than look them up ; to give the code more optimization opportunities. ! ; ??? Maybe when fields are recorded in opc.c, stop doing this, and ! ; pass a pointer to the recorded attributes instead. ! (gen-bool-attrs (if (eq? (mode:class (ifld-mode self)) 'INT) ! (atlist-cons (bool-attr-make 'SIGNED #t) ! (obj-atlist self)) ! (obj-atlist self)) ! gen-attr-mask) ", " (number->string (ifld-word-offset self)) ", " (number->string (ifld-start self #f)) ", " (number->string (ifld-length self)) --- 117,126 ---- (if need-extra? "value" varname) ; We explicitly pass the attributes here rather than look them up ; to give the code more optimization opportunities. ! ; ??? Maybe we should pass a pointer to the recorded attributes instead. ! ", " (gen-bool-attrs (obj-atlist self) gen-attr-mask) ", " (number->string (ifld-word-offset self)) ", " (number->string (ifld-start self #f)) ", " (number->string (ifld-length self))