Difference between revisions of "Instruction set: ARM"
(→Description key) |
(→Single register load/store instructions) |
||
Line 179: | Line 179: | ||
==Single register load/store instructions== | ==Single register load/store instructions== | ||
− | <nowiki>mnemonic<cond><B><T> Rd, | + | <nowiki>mnemonic<cond><B><T> Rd,address<!></nowiki><br> |
<nowiki>#exp has a range of +-4095 bytes.</nowiki><br> | <nowiki>#exp has a range of +-4095 bytes.</nowiki><br> | ||
+ | ! - Update Rn after use | ||
B - Byte transfer.<br> | B - Byte transfer.<br> | ||
T - Force address translation from a privileged mode. (Not pre-index) | T - Force address translation from a privileged mode. (Not pre-index) |
Revision as of 05:13, 3 June 2007
Contents
Description key
Field | Description |
---|---|
<> | Optional |
(x|y) | Either x or y but not both |
#exp | Constant expression or label |
Rn | one of R0-R15, LR, SP or PC |
Fn | one of F0-F7 |
S | Set condition codes |
Integer instructions (32 bit)
shift | Description |
---|---|
ASL (Rn|#exp) | Arithmetic shift left (LSL is preferred). |
LSL (Rn|#exp) | Logical shift left. |
ASR (Rn|#exp) | Arithmetic shift right. |
LSR (Rn|#exp) | Logical shift right. |
ROR (Rn|#exp) | Rotate right. |
RRX | Rotate right one bit with extend. LSB -> C, C -> MSB |
Flag | Description |
---|---|
N | Negative flag |
Z | Zero flag |
C | Carry flag |
V | Overflow flag |
I | Interrupt request disable |
F | Fast interrupt request disable |
cond | Description | Condition |
---|---|---|
AL | Always (normally omitted) | Any |
CC | Carry clear | C=0 |
CS | Carry set | C=1 |
EQ | Equal | Z=1 |
GE | Greater than or equal | N=V |
GT | Greater than | N=V and Z=0 |
HI | Higher (unsigned) | C=1 and Z=0 |
LE | Less than or equal | N<>V or Z=1 |
LS | Lower or same (unsigned) | C=0 or Z=1 |
LT | Less than | N<>V |
MI | Negative | N=1 |
NE | Not equal | Z=0 |
NV | Never (do not use) | N/A |
PL | Positive | N=0 |
VC | Overflow clear | V=0 |
VS | Overflow set | V=1 |
LO | Lower (unsigned) | Same as CC |
HS | Higher/same (unsigned) | Same as CS |
Arithmetic and logical instructions
mnemonic<cond><S> Rd,<Rn>,(#exp|Rm<,shift>)
#exp has a range of X ROR N*2 where X=0-255 and N=0-15
mnemonic | Description | Operation |
---|---|---|
ADC | Add with carry | Rd=Rn+Rm+C |
ADD | Add | Rd=Rn+Rm |
SBC | Subtract with carry | Rd=Rn-Rm-(1-C) |
SUB | Subtract | Rd=Rn-Rm |
RSC | Reverse subtract with carry | Rd=Rm-Rn-(1-C) |
RSB | Reverse subtract | Rd=Rm-Rn |
AND | Bitwise AND | Rd=Rn AND Rm |
BIC | Bitwise AND NOT | Rd=Rn AND (NOT Rm) |
ORR | Bitwise OR Register | Rd=Rn OR Rm |
EOR | Bitwise EOR | Rd=Rn EOR Rm |
MOV | Move | Rd=Rm |
MVN | Move NOT | Rd=NOT Rm |
Comparisons
mnemonic<cond><S|P> Rn,(#exp|Rm<,shift>)
#exp has a range of X ROR N*2 where X=0-255 and N=0-15
mnemonic | Description | Operation |
---|---|---|
CMN | Compare | Rn+Rm |
CMP | Compare | Rn-Rm |
TEQ | Test equal | Rn EOR Rm |
TST | Test | Rn AND Rm |
Multiply instructions
mnemonic<cond><S> Rd,Rm,Rs
mnemonic<cond><S> Rd,Rm,Rs,Rn
mnemonic | Description | Operation |
---|---|---|
MUL | Multiply | Rd=Rm*Rs |
MLA | Multiply-accumulate | Rd=Rm*Rs+Rn |
Branching instructions
mnemonic<cond> #exp
#exp has a range of +-223
mnemonic | Description | Operation |
---|---|---|
B | Branch | PC = PC + expression |
BL | Branch and link | R14 = PC + 4 & PSR, PC = PC + expression |
Single register load/store instructions
mnemonic<cond><B><T> Rd,address<!>
#exp has a range of +-4095 bytes.
! - Update Rn after use
B - Byte transfer.
T - Force address translation from a privileged mode. (Not pre-index)
mnemonic | Description | Operation |
---|---|---|
LDR | Load Register | Rd = [address] |
STR | Store Register | [address] = Rd |
address (pre-index) | address (post-index) |
---|---|
[Rn] | N/A |
[Rn, #exp]<!> | [Rn], #exp |
[Rn, <->Rm]<!> | [Rn], <->Rm |
[Rn, <->Rm, shift #s]<!> | [Rn], <->Rm, shift #s |
Multiple register load/store instructions
mnemonic<cond>type Rn<!>,{Rlist}<^>
{Rlist} - Any combination of registers.
If R15 is in {Rlist} then ^ will force update of PSR otherwise ^ maps {Rlist} to the User mode registers.
mnemonic | Description | Operation |
---|---|---|
LDM | Load Registerlist | {Rlist} = [Rn] |
STM | Store Registerlist | [Rn] = {Rlist} |
type | Block load/store | type | Stack pop | type | Stack push |
---|---|---|---|---|---|
IA | Increment Rn After | FD | Full Descending stack | EA | Empty Ascending stack |
IB | Increment Rn Before | ED | Empty Descending stack | FA | Full Ascending stack |
DA | Decrement Rn After | FA | Full Ascending stack | ED | Empty Descending stack |
DB | decrement Rn Before | EA | Empty Ascending stack | FD | Full Descending stack |
SWI instruction
mnemonic<cond> #exp
#exp has a range of 0-224
mnemonic | Description | Operation |
---|---|---|
SWI | Software interrupt | Jumps to the SWI vector |
Floating point coprosessor instructions
Flags
- IVO - Invalid operation
- REM - Remainder after floating point division
- DVZ - Division by zero
- OFL - Overflow
- UFL - Underflow
- INX - Inexact
prec
- S - Single (32 bit)
- D - Double (64 bit)
- E - Extended (80 bit)
- P - Packed BCD (96 bit)
round
- (default) - Round to nearest
- P - Round to +infinity
- M - Round to -infinity
- Z - Round to zero
Floating point data transfer
mnemonic<cond>prec Fd,[Rn]<,#offset> | [Rn,#offset]
Offset is the number of words from the base register (+/-1020 bytes)
mnemonic | Description | Operation |
---|---|---|
LDF | Load floating point | Fd = [addr] |
STF | Store floating point | [addr] = Fd |
Floating point data operations
mnemonic<cond>prec<round> Fd,<Fn>,(Fm|#exp)
mnemonic | Description | Operation |
---|---|---|
ADF | Add | Fd = Fn + Fm |
MUF | Multiply | Fd = Fn * Fm |
SUF | Subtract | Fd = Fn - Fm |
RSF | Reverse subtract | Fd = Fm - Fn |
DVF | Divide | Fd = Fn / Fm |
RDF | Reverse divide | Fd = Fm / Fn |
POW | Power | Fd = Fn to the power of Rm |
RPW | Reverse power | Fd = Fm to the power of Rn |
RMF | Remainder | Fd = remainder of Fn / Fm |
FML | Fast multiply | Fd = Fn * Fm |
FDV | Fast divide | Fd = Fn / Fm |
FRD | Fast reverse divide | Fd = Fm / Fn |
POL | Polar angle (ArcTan2) | Fd = polar angle of (Fn,Fm) |
MVF | Move | Fd = Fm |
MNF | Move negated | Fd = -Fm |
ABS | Absolute value | Fd = ABS(Fm) |
RND | Round to integral value | Fd = integer value of Fm |
SQT | Square root | Fd = Square root of Fm |
LOG | Logarithm to base 10 | Fd = logten of Fm |
LGN | Logarithm to base e | Fd = loge of Fm |
EXP | Exponent | Fd = e to the power of Fm |
SIN | Sine | Fd = sine of Fm |
COS | Cosine | Fd = cosine of Fm |
TAN | Tangent | Fd = tangent of Fm |
ASN | Arc sine | Fd = arcsine of Fm |
ACS | Arc cosine | Fd = arccosine of Fm |
ATN | Arc tangent | Fd = arctangent of Fm |
Valid values for #Exp:
- 0.0
- 1.0
- 2.0
- 3.0
- 4.0
- 5.0
- 0.5
- 10.0
Floating point register transfer
mnemonic | Description | Operation |
---|---|---|
FLT<cond>prec<round> | Integer to floating point | Fn = Rd |
FIX<cond>prec<round> | Floating point to integer | Rd = Fm (no constants, use MOV instead) |
WFS<cond> | Write floating point stauts | FPSR = Rd |
RFS<cond> | Read floating point status | Rd = FPSR |
WFC<cond> | Write floating point control | FPC = Rd (supervisor only) |
RFC<cond> | Read floating point control | Rd = FPC (supervisor only) |
Floating point comparisons
mnemonic<cond>prec<round> Fm,Fn
mnemonic | Description | Operation |
---|---|---|
CMF | Compare floating point | compare Fn with Fm |
CMN | Compare negated floating point | compare Fn with -Fm |
CMFE | Compare floating point with exception | compare Fn with Fm |
CNFE | Compare negated floating point with exception | compare Fn with -Fm |
Thumb instructions (16 bit)
Field | Updates | Action |
---|---|---|
MOV Rd, #<immed> | N Z | Rd := immed |
MOV Rd, Rm | N Z * * | Rd := Rm |
MOV Rd, Rm | Rd := Rm | |
CPY Rd, Rm | Rd := Rm | |
ADD Rd, Rn, #<immed> | N Z C V | Rd := Rn + immed |
ADD Rd, Rn, Rm | N Z C V | Rd := Rn + Rm |
ADD Rd, Rm | Rd := Rd + Rm | |
ADD Rd, #<immed> | N Z C V | Rd := Rd + immed |
ADC Rd, Rm | N Z C V | Rd := Rd + Rm + C-bit |
ADD SP, #<immed> | R13 := R13 + immed | |
ADD Rd, SP, #<immed> | Rd := R13 + immed | |
ADD Rd, PC, #<immed> | Rd := (R15 AND 0xFFFFFFFC) + immed | |
SUB Rd, Rn, Rm | N Z C V | Rd := Rn – Rm |
SUB Rd, Rn, #<immed> | N Z C V | Rd := Rn – immed |
SUB Rd, #<immed> | N Z C V | Rd := Rd – immed |
SBC Rd, Rm | N Z C V | Rd := Rd – Rm – NOT C-bit |
SUB SP, #<immed> | R13 := R13 – immed | |
NEG Rd, Rm | N Z C V | Rd := – Rm |
MUL Rd, Rm | N Z * * | Rd := Rm * Rd |
CMP Rn, Rm | N Z C V | update CPSR flags on Rn – Rm |
CMN Rn, Rm | N Z C V | update CPSR flags on Rn + Rm |
CMP Rn, #<immed> | N Z C V | update CPSR flags on Rn – immed |
NOP | None | |
AND Rd, Rm | N Z | Rd := Rd AND Rm |
EOR Rd, Rm | N Z | Rd := Rd EOR Rm |
ORR Rd, Rm | N Z | Rd := Rd OR Rm |
BIC Rd, Rm | N Z | Rd := Rd AND NOT Rm |
MVN Rd, Rm | N Z | Rd := NOT Rm |
TST Rn, Rm | N Z | update CPSR flags on Rn AND Rm |
LSL Rd, Rm, #<shift> | N Z C* | Rd := Rm << shift |
LSL Rd, Rs | N Z C* | Rd := Rd << Rs[7:0] |
LSR Rd, Rm, #<shift> | N Z C | Rd := Rm >> shift |
LSR Rd, Rs | N Z C | Rd := Rd >> Rs[7:0] |
ASR Rd, Rm, #<shift> | N Z C | Rd := Rm ASR shift |
ASR Rd, Rs | N Z C* | Rd := Rd ASR Rs[7:0] |
ROR Rd, Rs | N Z C* | Rd := Rd ROR Rs[7:0] |
REV Rd, Rm | Rd[31:24] := Rm[7:0], Rd[23:16] := Rm[15:8], Rd[15:8] := Rm[23:16], Rd[7:0] := Rm[31:24] | |
REV16 Rd, Rm | Rd[15:8] := Rm[7:0], Rd[7:0] := Rm[15:8], Rd[31:24] := Rm[23:16], Rd[23:16] := Rm[31: | |
REVSH Rd, Rm | Rd[15:8] := Rm[7:0], Rd[7:0] := Rm[15:8], Rd[31:16] := Rm[7] * &FFFF | |
LDR Rd, [Rn, #<immed>] | Rd := [Rn + immed] | |
LDRH Rd, [Rn, #<immed>] | Rd := ZeroExtend([Rn + immed][15:0]) | |
LDRB Rd, [Rn, #<immed>] | Rd := ZeroExtend([Rn + immed][7:0]) | |
LDR Rd, [Rn, Rm] | Rd := [Rn + Rm] | |
LDRH Rd, [Rn, Rm] | Rd := ZeroExtend([Rn + Rm][15:0]) | |
LDRSH Rd, [Rn, Rm] | Rd := SignExtend([Rn + Rm][15:0]) | |
LDRB Rd, [Rn, Rm] | Rd := ZeroExtend([Rn + Rm][7:0]) | |
LDRSB Rd, [Rn, Rm] | Rd := SignExtend([Rn + Rm][7:0]) | |
LDR Rd, [PC, #<immed>] | Rd := [(R15 AND 0xFFFFFFFC) + immed] | |
LDR Rd, [SP, #<immed>] | Rd := [R13 + immed] | |
LDMIA Rn!, <reglist> | Loads list of registers | |
STR Rd, [Rn, #<immed>] | [Rn + immed] := Rd | |
STRH Rd, [Rn, #<immed>] | [Rn + immed][15:0] := Rd[15:0] | |
STRB Rd, [Rn, #<immed>] | [Rn + immed][7:0] := Rd[7:0] | |
STR Rd, [Rn, Rm] | [Rn + Rm] := Rd | |
STRH Rd, [Rn, Rm] | [Rn + Rm][15:0] := Rd[15:0] | |
STRB Rd, [Rn, Rm] | [Rn + Rm][7:0] := Rd[7:0] | |
STR Rd, [SP, #<immed>] | [R13 + immed] := Rd | |
STMIA Rn!, <reglist> | Stores list of registers | |
PUSH <loreglist> | Push registers onto stack | |
PUSH <loreglist+LR> | Push LR and registers onto stack | |
POP <loreglist> | Pop registers from stack | |
POP <loreglist+PC> | Pop registers, branch to address loaded to PC | |
POP <loreglist+PC> | Pop, branch, and change to ARM state if address[0] = 0 | |
B{cond} label | R15 := label | |
B label | R15 := label | |
BL label | R14 := address of next instruction, R15 := label | |
BX Rm | R15 := Rm AND 0xFFFFFFFE | |
BLX label | R14 := address of next instruction, R15 := label Change to ARM | |
BLX Rm | R14 := address of next instruction, R15 := Rm AND 0xFFFFFFFE | |
SXTH Rd, Rm | Rd[31:0] := SignExtend(Rm[15:0]) | |
SXTB Rd, Rm | Rd[31:0] := SignExtend(Rm[7:0]) | |
UXTH Rd, Rm | Rd[31:0] := ZeroExtend(Rm[15:0]) | |
UXTB Rd, Rm | Rd[31:0] := ZeroExtend(Rm[7:0]) | |
SWI <immed_8> | Software interrupt processor exception | |
CPSID <iflags> | Disable specified interrups | |
CPSIE <iflags> | Enable specified interrups | |
SETEND <endianness> | Sets endianness for loads and saves. | |
BKPT <immed_8> | Prefetch abort or enter debug state |
Vector Floating Point Instruction Set
Instruction | Exceptions | Action |
---|---|---|
FMUL<S/D>{cond} Fd, Fn, Fm | IO, OF, UF, IX | Fd := Fn * Fm |
FNMUL<S/D>{cond} Fd, Fn, Fm | IO, OF, UF, IX | Fd := - (Fn * Fm) |
FMAC<S/D>{cond} Fd, Fn, Fm | IO, OF, UF, IX | Fd := Fd + (Fn * Fm) |
FNMAC<S/D>{cond} Fd, Fn, Fm | IO, OF, UF, IX | Fd := Fd - (Fn * Fm) |
FMSC<S/D>{cond} Fd, Fn, Fm | IO, OF, UF, IX | Fd := - Fd + (Fn * Fm) |
FNMSC<S/D>{cond} Fd, Fn, Fm | IO, OF, UF, IX | Fd := - Fd - (Fn * Fm) |
FADD<S/D>{cond} Fd, Fn, Fm | IO, OF, IX | Fd := Fn + Fm |
FSUB<S/D>{cond} Fd, Fn, Fm | IO, OF, IX | Fd := Fn - Fm |
FDIV<S/D>{cond} Fd, Fn, Fm | IO, DZ, OF, UF, IX | Fd := Fn / Fm |
FCPY<S/D>{cond} Fd, Fm | Fd := Fm | |
FABS<S/D>{cond} Fd, Fm | Fd := abs(Fm) | |
FNEG<S/D>{cond} Fd, Fm | Fd := - Fm | |
FSQRT<S/D>{cond} Fd, Fm | IO, IX | Fd := sqrt(Fm) |
FCMP{E}<S/D>{cond} Fd, Fm | IO | Set FPSCR flags on Fd - Fm |
FCMP{E}Z<S/D>{cond} Fd | IO | Set FPSCR flags on Fd - 0 |
FCVTDS{cond} Dd, Sm | IO | Dd := convertStoD(Sm) |
FCVTSD{cond} Sd, Dm | IO, OF, UF, IX | Sd := convertDtoS(Dm) |
FUITO<S/D>{cond} Fd, Sm | IX | Fd := convertUItoF(Sm) |
FSITO<S/D>{cond} Fd, Sm | IX | Fd := convertSItoF(Sm) |
FTOUI{Z}<S/D>{cond} Sd, Fm | IO, IX | Sd := convertFtoUI(Fm) |
FTOSI{Z}<S/D>{cond} Sd, Fm | IO, IX | Sd := convertFtoSI(Fm) |
FST<S/D>{cond} Fd, [Rn{, #<immed>}] | [address] := Fd. Immediate range 0-1020, multiple of 4. | |
FSTMIA<S/D/X>{cond} Rn, <VFPregs> | Saves list of VFP registers, starting at address in Rn. | |
FSTMIA<S/D/X>{cond} Rn!, <VFPregs> | synonym: FSTMEA (empty ascending) | |
FSTMDB<S/D/X>{cond} Rn!, <VFPregs> | synonym: FSTMFD (full descending) | |
FLD<S/D>{cond} Fd, [Rn{, #<immed>}] | Fd := [address]. Immediate range 0-1020, multiple of 4. | |
FLDMIA<S/D/X>{cond} Rn, <VFPregs> | Loads list of VFP registers, starting at address in Rn. | |
FLDMIA<S/D/X>{cond} Rn!, <VFPregs> | synonym: FLDMFD (full descending) | |
FLDMDB<S/D/X>{cond} Rn!, <VFPregs> | synonym: FLDMEA (empty ascending) | |
FMSR{cond} Sn, Rd | Sn := Rd | |
FMRS{cond} Rd, Sn | Rd := Sn | |
FMSRR{cond} {Sn,Sm}, Rd, Rn | Sn := Rd, Sm := Rn | |
FMRRS{cond} Rd, Rn, {Sn,Sm} | Rd := Sn, Rn := Sm | |
FMDRR{cond} Dn, Rd, Rn | Dn[31:0] := Rd, Dn[63:32] := Rn | |
FMRRD{cond} Rd, Rn, Dn | Rd := Dn[31:0], Rn := Dn[63:32] | |
FMDLR{cond} Dn, Rd | Dn[31:0] := Rd | |
FMRDL{cond} Rd, Dn | Rd := Dn[31:0] | |
FMDHR{cond} Dn, Rd | Dn[63:32] := Rd | |
FMRDH{cond} Rd, Dn | Rd := Dn[63:32] | |
FMXR{cond} <VFPsysreg>, Rd | VFPsysreg := Rd | |
FMRX{cond} Rd, <VFPsysreg> | Rd := VFPsysreg | |
FMSTAT{cond} | CPSR flags := FPSCR flags |