The instructions to be described on this page have the formats shown in this diagram:
The 16-bit instructions do not include memory-reference instructions, or the subroutine jump instruction. However, while the set of 16-bit instructions is therefore not complete in itself, it is sufficient that a large proportion of the instructions in a program could be 16-bit instructions.
Line 1 gives the format of the operate instructions. Integer instructions reference the integer registers, and floating-point instructions reference the floating-point registers, as might be expected.
In each case, the destination register can only be one of registers 0 through 7, while the source register may be any register from 0 to 31. As a result, although these are register-to-register instructions, the store instruction, as well as the load instruction, is meaningful.
There are 96 possible opcodes, as the first two bits of an opcode may not be both 1, as these combinations are reserved for other 16-bit instructions.
The opcodes (with the first four bits appearing along the top of the chart, and the last three bits appearing on the right) are:
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 SWB IB SWH IH SW I SWL SWM SWF SWD SWQ 000 CB CH C CL CM CF CD CQ 001 LB ULB LH ULH L UL LL LM LF LD LQ 010 STB XB STH XH ST X STL XL STM STF STD STQ 011 AB NB AH NH A N AL NL AM AF AD AQ 100 SB OB SH OH S O SL OL SM SF SD SQ 101 MH MEH M ME ML MEL MM MF MD MQ 110 DH DEH D DE DL DEL DM DF DD DQ 111
The different instructions are:
For integer types:
SW SWAP Exchange the contents of the source and destination locations C COMPARE Subtract the contents of the source location from the contents of the destination location, but with the operation modified so that overflow cannot possibly result, and set the condition codes appropriately without modifying the destination location L LOAD Place the contents of the source operand in the destination register; if the type involved is smaller than the register, perform sign extension ST STORE Fill the destination location from the least significant part of the source location A ADD Add the contents of the source and destination locations, placing the result in the destination location S SUBTRACT Subtract the contents of the source location from those of the destination location, placing the result in the source location M MULTIPLY Multiply the contents of the source and destination locations, placing the least significant part of the result of the same length as the two input operands in the destination location, with sign extension if that is shorter than the length of the destination register D DIVIDE Divide the contents of the source location by the contents of the destination location, placing the quotient in the destination location I INSERT Fill the least significant bits of the destination register with the contents of the source location, leaving the rest of the destination register unaffected UL UNSIGNED LOAD Fill the least significant bits of the destination register with the contents of the source location, and clear the remaining more significant bits of the destination register X EXCLUSIVE OR Perform a bitwise Exclusive OR operation between the contents of the source and destination locations, placing the result in the desination location N AND Perform a bitwise Logical AND operation between the contents of the source and destination locations, placing the result in the desination location O OR Perform a bitwise Logical OR operation between the contents of the source and destination locations, placing the result in the desination location ME MULTIPLY EXTENSIBLY Multiply the contents of the source and destination locations. Take the full product, as an integer having twice the size as that of the source and the destination, and: - in the case of the halfword and integer versions of the instruction, place it in the destination register, with sign extension in the halfword version; - in the case of the long version of the instruction, place the most significannt half of the result in the destination register, which must be an even-numbered register, and place the least significant half of the result in the register following DE DIVIDE EXTENSIBLY Divide a destination operand of twice the length of that indicated by the instruction type (and located as the result of the MULTIPLY EXTENSIBLY instruction) by the source operand; store the double length quotient in the destination location (again following the MULTIPLY EXTENSIBLY result placement) and the single length remainder in the next register following those that are used. Whenever a result is not wide enough to fill a register, sign extension is performed. Division is performed giving a result as if both operands were converted to positive numbers before starting, with the signs then set afterwards to give a correct result based on the actual signs of the operands. Thus both the quotient and the remainder will be positive or zero if the dividend and divisor have the same sign, and both will be negative or zero if they are of opposite signs.
The possible integer types, and the suffixes that indicate them, are:
B BYTE An 8-bit two's complement integer H HALFWORD A 16-bit two's complement integer INTEGER A 32-bit two's complement integer L LONG A 64-bit two's complement integer
The integer registers are 64 bits long, to contain the longest of these types.
The available floating-point operations are SWAP, LOAD, STORE, ADD, SUBTRACT, MULTIPLY, and DIVIDE. Their functions are basically the same as those of the corresponding integer operations, except that floating-point arithmetic is performed.
The possible floating-point types for 16-bit instructions, and the suffixes that indicate them, are:
M MEDIUM A 48-bit floating-point number (preferably aligned on 16-bit boundaries) F FLOATING A 32-bit floating-point number D DOUBLE A 64-bit floating-point number Q QUAD A 128-bit floating-point number
with their formats as indicated within this diagram:
These instructions are then also suffixed RC for Register Compact to indicate the addressing mode.
Lines 2 through 9 of the diagram illustrate the 16-bit shift and rotate instructions. These are:
140xxx LSLLC Logical Shift Left Long Compact 141xxx LSRLC Logical Shift Right Long Compact 142xxx ASLLC Arithmetic Shift Left Long Compact 143xxx ASRLC Arithmetic Shift Right Long Compact 1500xx LSLC Logical Shift Left Compact 1510xx LSRC Logical Shift Right Compact 1520xx ASLC Arithmetic Shift Left Compact 1530xx ASRC Arithmetic Shift Right Compact 1504xx LSLHC Logical Shift Left Halfword Compact 1514xx LSRHC Logical Shift Right Halfword Compact 1524xx ASLHC Arithmetic Shift Left Halfword Compact 1634xx ASRHC Arithmetic Shift Right Halfword Compact 1506xx LSLBC Logical Shift Left Byte Compact 1516xx LSRBC Logical Shift Right Byte Compact 1526xx ASLBC Arithmetic Shift Left Byte Compact 1536xx ASRBC Arithmetic Shift Right Byte Compact 160xxx RLLC Rotate Left Long Compact 161xxx RRLC Rotate Right Long Compact 1620xx RLC Rotate Left Compact 1630xx RRC Rotate Right Compact 1624xx RLHC Rotate Left Halfword Compact 1634xx RRHC Rotate Right Halfword Compact 1626xx RLBC Rotate Left Byte Compact 1636xx RRBC Rotate Right Byte Compact
Logical right and left shifts insert zeroes; the arithmetic right shift inserts a copy of the existing value of the most significant bit into the leftmost position of the word so as to maintain the sign as either negative or non-negative.
An arithmetic left shift inserts zeroes into the leftmost end of a number regardless of its sign, just like a logical left shift, but it differs in that the overflow bit is set if a left shift results in a change of the sign of the value being shifted, instead of merely a carry out of that value.
Line 10 of the diagram shows the branch instructions.
The displacement is an 8-bit signed value, in two's complement form, which may vary from -128 to +127. The displacement is in units of 32 bits. No attempt is made to skip over values corresponding to the 32-bit instruction slots containing header information. A displacement of zero refers to the instruction slot following that in which the instruction is located, whether the instruction is found in the first or second half of the instruction slot in which it is located, therefore a branch with a displacement of zero is only equivalent to a no-operation if it occurs in the second half of an instruction slot.
The available branch instructions are:
1704xx BL Branch if Low 1710xx BE Branch if Equal 1714xx BLE Branch if Low or Equal 1720xx BH Branch if High 1724xx BNE Branch if Not Equal 1730xx BHE Branch if High or Equal 1734xx BNV Branch if No Overflow 1740xx BV Branch if Overflow 1750xx BC Branch if Carry 1754xx BNC Branch if No Carry 1774xx B Branch
Line 11 of the diagram shows how condition values that are invalid result instead in an additional category of instructions which affect the flags used for predicated instructions.
1700xx CTF Condition to Flag Set flag to 1 if condition valid; set flag to 0 if condition not met 1760xx SFC Set Flag on Condition Set flag to 1 if condition met; leave it unaffected otherwise 1764xx CFC Clear Flag on Condition Set flag to 0 if condition met; leave it unaffected otherwise
Note that the format of this instruction is such that it can potentially manipulate up to 16 flags, although most of the time the predicated instructions in VLIW mode, Mode 3, only use eight flags, and those in Simple Block Mode, Mode 2, only use four flags. However, both Simple Block Mode and VLIW mode include at least one block format (each such format being unique to one of those modes, of course) using all sixteen flags.
As one of the possible 16-bit prefixes in the 32-bit opcode space used for Prefix Mode causes a permanent switch to 16-bit instructions, it is reasonable to have some means of switching back to ordinary instructions from 32-bit opcode space. This would also only be applicable to Mode 1, Prefix Mode, where instructions are effectively interpreted one at a time.
For a number of other reasons as well, the prefixes to be described below can only be used when in any permanent 16-bit mode, and not when in a string of from 1 to 255 16-bit instructions indicated by a closely related 16-bit prefix in 32-bit opcode space.
This is shown in the ninth line of the diagram above, where the format of the Set Mode instruction is shown.
16276x SMC Set Mode Compact 16376x MPC Mode Prefix Compact
The four bit mode field in this instruction can be used to switch from Mode 4, 16-bit mode, to other modes. However, unless the prefix is located in a 16-bit halfword immediately preceding an aligned 256-bit block boundary, switching to any mode from Mode 12 to Mode 15, all of which involve organizing instructions into 256-bit blocks, will not be permitted, as it would not work properly.
The Mode Prefix instruction allows executing individual instructions from other modes without changing mode, so after a single instruction from the other mode is executed, the following instructions are again interpreted according to Mode 4.
The first four lines of the diagram, and the sixth and seventh lines of the diagram show that the ability to dedicate part of the 16-bit opcode space to prefixes permits including memory-reference instructions in a 16-bit instruction stream that only take up 32 bits, without additional overhead for switching modes.
15070x xxxxxx LBC Load Byte Compact 15071x xxxxxx STBC Store Byte Compact 15072x xxxxxx ULBC Unsigned Load Byte Compact 15073x xxxxxx IBC Insert Byte Compact 15170x xxxxxx LHC Load Halfword Compact 15171x xxxxxx STHC Store Halfword Compact 15172x xxxxxx ULHC Unsigned Load Halfword Compact 15173x xxxxxx IHC Insert Halfword Compact 15270x xxxxxx LC Load Compact 15271x xxxxxx STC Store Compact 15272x xxxxxx ULC Unsigned Load Compact 15273x xxxxxx IC Insert Compact 15370x xxxxxx LLC Load Long Compact 15371x xxxxxx STLC Store Long Compact 15372x xxxxxx LAC Load Address Compact 15470x xxxxxx LMC Load Medium Compact 15471x xxxxxx STMC Store Medium Compact 15472x xxxxxx LFC Load Floating Compact 15473x xxxxxx STFC Store Floating Compact 15570x xxxxxx LDC Load Double Compact 15571x xxxxxx STDC Store Double Compact 15572x xxxxxx LQC Load Quad Compact 15573x xxxxxx STQC Store Quad Compact 150741 xxxxxx JLC Jump if Low Compact 150742 xxxxxx JEC Jump if Equal Compact 150743 xxxxxx JLEC Jump if Low or Equal Compact 150744 xxxxxx JHC Jump if High Compact 150745 xxxxxx JNEC Jump if Not Equal Compact 150746 xxxxxx JHEC Jump if High or Equal Compact 150747 xxxxxx JNVC Jump if No Overflow Compact 150750 xxxxxx JVC Jump if Overflow Compact 150752 xxxxxx JCC Jump if Carry Compact 150753 xxxxxx JNCC Jump if No Carry Compact 150757 xxxxxx JMPC Jump Compact 16270x xxxxxx JSRC Jump to Subroutine Compact 16370x xxxxxx JXC Jump indexed Compact
As is visible in the diagram, due to the limited opcode space available for 16-bit headers, the destination register field is only three bits long, and so memory reference instructions may only load to, or store from, registers 0 through 7.
However, there was enough opcode space available to allow the JSRC instruction to have a full five-bit return register field. As well, the JXC instruction uses the same five bits for an index register field, allowing an instruction within 16-bit mode for returning from a subroutine.
Note that the 16-bit prefixes are split between two regions of 16-bit opcode space; those shown in the first four lines of the diagram immediately follow the shift instructions, and those shown in the last three lines of the diagram immediately follow the rotate instructions.
Hybrid mode, to be discussed on the next page, uses a modified form of the 16-bit instructions that fit entirely in the first half of the address space only. One of the alterations required to achieve this is the elimination of the region in 16-bit opcode space used for rotate instructions.
Thus, in order that it will remain available in Hybrid Mode after modification, the prefix shown in the fifth line of the diagram was placed in the area following the shift instructions and not the rotate instructions.
These prefixes are used when control flow guidance is enabled; they are to be placed at all locations to which control flow may be transferred, and their values have the following meanings:
157770 Permitted target for a jump or branch instruction 157771 Permitted target for a return from subroutine 157772 Permitted target for a subroutine call instruction 157773 Permitted target for a non-advancing subroutine call instruction
As noted on the main page of this section, a non-advancing subroutine call instruction is one that is used to perform a jump which places the current address in register for another use, such as for initializing a base register, and is not actually calling a subroutine; this needs to be indicated in order for a shadow stack to function properly, and is needed because there is no distinctive non-branching version of the jump to subroutine instruction to save the current address in this architecture, correspoding to BALR on the IBM System/360.
However, given that there is a program-counter-relative addressing mode, it is true that the Load Address instruction can be used to save the current address to a register without the least inclination to perform a branch.