aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJose E. Marchesi <jose.marchesi@oracle.com>2020-06-04 16:15:53 +0200
committerJose E. Marchesi <jose.marchesi@oracle.com>2020-06-04 16:17:42 +0200
commite9bffec9afc45cf7c49308f0b4b8cc6bf68f58f2 (patch)
tree9c098c794ab1b2a96fb18ccf298e23daef9f0b8d /include
parentb3db6d07be467fe86f5b4185a8fc7bec49380c1f (diff)
downloadbinutils-e9bffec9afc45cf7c49308f0b4b8cc6bf68f58f2.zip
binutils-e9bffec9afc45cf7c49308f0b4b8cc6bf68f58f2.tar.gz
binutils-e9bffec9afc45cf7c49308f0b4b8cc6bf68f58f2.tar.bz2
opcodes: discriminate endianness and insn-endianness in CGEN ports
The CGEN support code in opcodes accesses instruction contents using a couple of functions defined in cgen-opc.c: cgen_get_insn_value and cgen_put_insn_value. These functions use the "instruction endianness" in the CPU description to order the read/written bytes. The process of writing an instruction to the object file is: a) cgen_put_insn_value ;; Writes out the opcodes. b) ARCH_cgen_insert_operand insert_normal insert_1 cgen_put_insn_value ;; Writes out the bytes of the ;; operand. Likewise, the process of reading an instruction from the object file is: a) cgen_get_insn_value ;; Reads the opcodes. b) ARCH_cgen_extract_operand extract_normal extract_1 cgen_get_insn_value ;; Reads in the bytes of the ;; operand. As can be seen above, cgen_{get,put}_insn_value are used to both process the instruction opcodes (the constant fields conforming the base instruction) and also the values of the instruction operands, such as immediates. This is problematic for architectures in which the endianness of instructions is different to the endianness of data. An example is BPF, where instructions are always encoded big-endian but the data may be either big or little. This patch changes the cgen_{get,put}_insn_value functions in order to get an extra argument with the endianness to use, and adapts the existin callers to these functions in order to provide cd->endian or cd->insn_endian, whatever appropriate. Callers like extract_1 and insert_1 pass cd->endian (since they are reading/writing operand values) while callers reading/writing the base instruction pass cd->insn_endian instead. A few little adjustments have been needed in some existing CGEN based ports: * The BPF assembler uses cgen_put_insn_value. It has been adapted to pass the new endian argument. * The mep port has code in mep.opc that uses cgen_{get,put}_insn_value. It has been adapted to pass the new endianargument. Ditto for a call in the assembler. Tested with --enable-targets=all. Regested in all supported targets. No regressions. include/ChangeLog: 2020-06-04 Jose E. Marchesi <jose.marchesi@oracle.com> * opcode/cgen.h: Get an `endian' argument in both cgen_get_insn_value and cgen_put_insn_value. opcodes/ChangeLog: 2020-06-04 Jose E. Marchesi <jose.marchesi@oracle.com> * cgen-opc.c (cgen_get_insn_value): Get an `endian' argument. (cgen_put_insn_value): Likewise. (cgen_lookup_insn): Pass endianness to cgen_{get,put}_insn_value. * cgen-dis.in (print_insn): Likewise. * cgen-ibld.in (insert_1): Likewise. (insert_1): Likewise. (insert_insn_normal): Likewise. (extract_1): Likewise. * bpf-dis.c: Regenerate. * bpf-ibld.c: Likewise. * bpf-ibld.c: Likewise. * cgen-dis.in: Likewise. * cgen-ibld.in: Likewise. * cgen-opc.c: Likewise. * epiphany-dis.c: Likewise. * epiphany-ibld.c: Likewise. * fr30-dis.c: Likewise. * fr30-ibld.c: Likewise. * frv-dis.c: Likewise. * frv-ibld.c: Likewise. * ip2k-dis.c: Likewise. * ip2k-ibld.c: Likewise. * iq2000-dis.c: Likewise. * iq2000-ibld.c: Likewise. * lm32-dis.c: Likewise. * lm32-ibld.c: Likewise. * m32c-dis.c: Likewise. * m32c-ibld.c: Likewise. * m32r-dis.c: Likewise. * m32r-ibld.c: Likewise. * mep-dis.c: Likewise. * mep-ibld.c: Likewise. * mt-dis.c: Likewise. * mt-ibld.c: Likewise. * or1k-dis.c: Likewise. * or1k-ibld.c: Likewise. * xc16x-dis.c: Likewise. * xc16x-ibld.c: Likewise. * xstormy16-dis.c: Likewise. * xstormy16-ibld.c: Likewise. gas/ChangeLog: 2020-06-04 Jose E. Marchesi <jose.marchesi@oracle.com> * cgen.c (gas_cgen_finish_insn): Pass the endianness to cgen_put_insn_value. (gas_cgen_md_apply_fix): Likewise. (gas_cgen_md_apply_fix): Likewise. * config/tc-bpf.c (md_apply_fix): Pass data endianness to cgen_put_insn_value. * config/tc-mep.c (mep_check_ivc2_scheduling): Pass endianness to cgen_put_insn_value. cpu/ChangeLog: 2020-06-02 Jose E. Marchesi <jose.marchesi@oracle.com> * mep.opc (print_slot_insn): Pass the insn endianness to cgen_get_insn_value.
Diffstat (limited to 'include')
-rw-r--r--include/ChangeLog5
-rw-r--r--include/opcode/cgen.h4
2 files changed, 7 insertions, 2 deletions
diff --git a/include/ChangeLog b/include/ChangeLog
index df4208e..e0bef67 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2020-06-04 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * opcode/cgen.h: Get an `endian' argument in both
+ cgen_get_insn_value and cgen_put_insn_value.
+
2020-06-04 Jose E. Marchesi <jemarch@gnu.org>
* opcode/cgen.h (enum cgen_cpu_open_arg): New value
diff --git a/include/opcode/cgen.h b/include/opcode/cgen.h
index 3f32544..cae2795 100644
--- a/include/opcode/cgen.h
+++ b/include/opcode/cgen.h
@@ -1463,9 +1463,9 @@ extern const CGEN_INSN * cgen_lookup_get_insn_operands
/* Cover fns to bfd_get/set. */
extern CGEN_INSN_INT cgen_get_insn_value
- (CGEN_CPU_DESC, unsigned char *, int);
+ (CGEN_CPU_DESC, unsigned char *, int, int);
extern void cgen_put_insn_value
- (CGEN_CPU_DESC, unsigned char *, int, CGEN_INSN_INT);
+ (CGEN_CPU_DESC, unsigned char *, int, CGEN_INSN_INT, int);
extern CGEN_INSN_INT cgen_get_base_insn_value
(CGEN_CPU_DESC, unsigned char *, int);