as: V850 Opcodes
1
1 9.49.5 Opcodes
1 --------------
1
1 'as' implements all the standard V850 opcodes.
1
1 'as' also implements the following pseudo ops:
1
1 'hi0()'
1 Computes the higher 16 bits of the given expression and stores it
1 into the immediate operand field of the given instruction. For
1 example:
1
1 'mulhi hi0(here - there), r5, r6'
1
1 computes the difference between the address of labels 'here' and
1 'there', takes the upper 16 bits of this difference, shifts it down
1 16 bits and then multiplies it by the lower 16 bits in register 5,
1 putting the result into register 6.
1
1 'lo()'
1 Computes the lower 16 bits of the given expression and stores it
1 into the immediate operand field of the given instruction. For
1 example:
1
1 'addi lo(here - there), r5, r6'
1
1 computes the difference between the address of labels 'here' and
1 'there', takes the lower 16 bits of this difference and adds it to
1 register 5, putting the result into register 6.
1
1 'hi()'
1 Computes the higher 16 bits of the given expression and then adds
1 the value of the most significant bit of the lower 16 bits of the
1 expression and stores the result into the immediate operand field
1 of the given instruction. For example the following code can be
1 used to compute the address of the label 'here' and store it into
1 register 6:
1
1 'movhi hi(here), r0, r6' 'movea lo(here), r6, r6'
1
1 The reason for this special behaviour is that movea performs a sign
1 extension on its immediate operand. So for example if the address
1 of 'here' was 0xFFFFFFFF then without the special behaviour of the
1 hi() pseudo-op the movhi instruction would put 0xFFFF0000 into r6,
1 then the movea instruction would takes its immediate operand,
1 0xFFFF, sign extend it to 32 bits, 0xFFFFFFFF, and then add it into
1 r6 giving 0xFFFEFFFF which is wrong (the fifth nibble is E). With
1 the hi() pseudo op adding in the top bit of the lo() pseudo op, the
1 movhi instruction actually stores 0 into r6 (0xFFFF + 1 = 0x0000),
1 so that the movea instruction stores 0xFFFFFFFF into r6 - the right
1 value.
1
1 'hilo()'
1 Computes the 32 bit value of the given expression and stores it
1 into the immediate operand field of the given instruction (which
1 must be a mov instruction). For example:
1
1 'mov hilo(here), r6'
1
1 computes the absolute address of label 'here' and puts the result
1 into register 6.
1
1 'sdaoff()'
1 Computes the offset of the named variable from the start of the
1 Small Data Area (whose address is held in register 4, the GP
1 register) and stores the result as a 16 bit signed value in the
1 immediate operand field of the given instruction. For example:
1
1 'ld.w sdaoff(_a_variable)[gp],r6'
1
1 loads the contents of the location pointed to by the label
1 '_a_variable' into register 6, provided that the label is located
1 somewhere within +/- 32K of the address held in the GP register.
1 [Note the linker assumes that the GP register contains a fixed
1 address set to the address of the label called '__gp'. This can
1 either be set up automatically by the linker, or specifically set
1 by using the '--defsym __gp=<value>' command line option].
1
1 'tdaoff()'
1 Computes the offset of the named variable from the start of the
1 Tiny Data Area (whose address is held in register 30, the EP
1 register) and stores the result as a 4,5, 7 or 8 bit unsigned value
1 in the immediate operand field of the given instruction. For
1 example:
1
1 'sld.w tdaoff(_a_variable)[ep],r6'
1
1 loads the contents of the location pointed to by the label
1 '_a_variable' into register 6, provided that the label is located
1 somewhere within +256 bytes of the address held in the EP register.
1 [Note the linker assumes that the EP register contains a fixed
1 address set to the address of the label called '__ep'. This can
1 either be set up automatically by the linker, or specifically set
1 by using the '--defsym __ep=<value>' command line option].
1
1 'zdaoff()'
1 Computes the offset of the named variable from address 0 and stores
1 the result as a 16 bit signed value in the immediate operand field
1 of the given instruction. For example:
1
1 'movea zdaoff(_a_variable),zero,r6'
1
1 puts the address of the label '_a_variable' into register 6,
1 assuming that the label is somewhere within the first 32K of
1 memory. (Strictly speaking it also possible to access the last 32K
1 of memory as well, as the offsets are signed).
1
1 'ctoff()'
1 Computes the offset of the named variable from the start of the
1 Call Table Area (whose address is held in system register 20, the
1 CTBP register) and stores the result a 6 or 16 bit unsigned value
1 in the immediate field of then given instruction or piece of data.
1 For example:
1
1 'callt ctoff(table_func1)'
1
1 will put the call the function whose address is held in the call
1 table at the location labeled 'table_func1'.
1
1 '.longcall name'
1 Indicates that the following sequence of instructions is a long
1 call to function 'name'. The linker will attempt to shorten this
1 call sequence if 'name' is within a 22bit offset of the call. Only
1 valid if the '-mrelax' command line switch has been enabled.
1
1 '.longjump name'
1 Indicates that the following sequence of instructions is a long
1 jump to label 'name'. The linker will attempt to shorten this code
1 sequence if 'name' is within a 22bit offset of the jump. Only
1 valid if the '-mrelax' command line switch has been enabled.
1
1 For information on the V850 instruction set, see 'V850 Family
1 32-/16-Bit single-Chip Microcontroller Architecture Manual' from NEC.
1 Ltd.
1