[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6. Opcodes support

Opcodes support comes in the form of machine generated opcode tables as well as supporting routines.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.1 Generated files

The basic interface is defined by ‘include/opcode/cgen.h’ which is included by the machine generated ‘<arch>-desc.h’. ‘opcode/cgen.h’ can stand on its own for the target independent stuff, but to get target specific parts of the interface use ‘<arch>-desc.h’.

The generated files are:

<arch>-desc.h

Defines macros, enums, and types used to describe the chip.

<arch>-desc.c

Tables of various things describing the chip. This does not include assembler syntax nor semantic information.

<arch>-ibld.c

Routines for constructing and deconstructing instructions.

<arch>-opc.h

Declarations necessary for assembly/disassembly that aren't used elsewhere and thus left out of ‘<arch>-desc.h’.

<arch>-opc.c

Assembler syntax tables.

<arch>-asm.c

Assembler support routines.

<arch>-dis.c

Disassembler support routines.

<arch>-opinst.c

Operand instance tables. These describe which hardware elements are read and which are written for each instruction. This file isn't generated for all architectures, only ones that can make use of the data. For example the M32R uses them to emit warnings if the output of one parallel instruction is the input of another, and to control creating parallel instructions during optimizing assembly.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.2 The .opc file

Files with suffix ‘.opc’ (e.g. ‘m32r.opc’) contain target specific C code that accompanies the cpu description file. The ‘.opc’ file is split into 4 sections:


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.3 Special assembler parsing needs

Often parsing of assembly instructions requires more than what a program-generated assembler can handle. For example one version of an instruction may only accept certain registers, rather than the entire set.

Here's an example taken from the ‘m32r’ architecture.

32 bit addresses are built up with a two instruction sequence: one to load the high 16 bits of a register, and another to or-in the lower 16 bits.

 
seth r0,high(some_symbol)
or3  r0,r0,low(some_symbol)

When assembling, special code must be called to recognize the high and low pseudo-ops and generate the appropriate relocations. This is indicated by specifying a "parse handler" for the operand in question. Here is the define-operand for the lower 16 bit operand.

 
(define-operand
  (name ulo16)
  (comment "16 bit unsigned immediate, for low()")
  (attrs)
  (type h-ulo16)
  (index f-uimm16)
  (handlers (parse "ulo16"))
)

The generated parser will call a function named parse_ulo16 for the immediate operand of the or3 instruction. The name of the function is constructed by prepended "parse_" to the argument of the parse spec.

 
errmsg = parse_ulo16 (cd, strp, M32R_OPERAND_ULO16, &fields->f_uimm16);

But where does one put the parse_ulo16 function? Answer: in the ‘asm.c’ section of ‘m32r.opc’.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Doug Evans on January, 28 2010 using texi2html 1.78.