Assign all flags |
; Precondition: user-mode, or known PSR;
; also PSR non-zero - can precede with
; TEQ R0, R0 if not
TEQ PC, PC
TEQNEP PC, #0x??00000?
MSR CPSR_f, #0x?0000000 ; no-op on ARMv2
; Precondition: Rd available
MOV Rd, PC
BICS Rd, Rd, #0xF0000000 ; (set C)
TEQ PC, PC
TEQNEP Rd, #0x?0000000
MSR CPSR_f, #0x?0000000 ; no-op on ARMv2
; Rn=NZCVxxxx...x, Rt available
MOV Rt, Rn LSL #3
CMN Rt, #0x80000000 ; assign V
MOVS Rt, Rn ASR #30 ; assign C
TEQ Rt, #1 ; assign N, Z
; Note that it's not possible to set both N and Z without
; directly writing the PSR, so N set will force Z clear
; Rn=NZCVxxxx...x, Ru=1<<31, Rv=1
CMN Ru, Rn LSL #3 ; assign V
TEQ Rv, Rn ASR #30 ; assign C, N, Z
; Rn=(V⊕N)NZ̅Cxxxx...x, Rt (or Rd) available
ADDS Rt, Rd, Rd ; assign V
MOVS Rt, Rt ASR #30 ; assign C, N, Z
; Rn=N(V⊕N)Z̅Z̅0000...000C
CMN Rn, Rn ; assign V
TST Rn, Rn RRX ; assign C, N, Z
; Rn=1V̅Z̅CN010...0
CMN Rn, Rn ; assign V
TST Rn, Rn LSL #4 ; assign C, N, Z
; Rn=N(V⊕N)Z̅Cxxxx...xx01
CMN Rn, Rn ; assign V
TST Rn, Rn ASR #29 ; assign C, N, Z
; Rn=1V̅1xxxxx...xCN0Z̅
CMN Rn, Rn ; assign V
TST Rn, Rn LSL #29 ; assign C, N, Z
|
; Precondition: user-mode, or known PSR
TEQP PC, #0x??00000?
; Precondition: Rd=0x0C000003 or Rd=~0xF0000000
AND Rd, Rd, PC
TEQP Rd, #0x?0000000
; Precondition: Rd available
MOV Rd, PC
BIC Rd, Rd, #0xF0000000
TEQP Rd, #0x?0000000
|
MSR CPSR_f, #0x?0000000
|
Extract all flags |
MOV Rd, PC
MRS Rd, CPSR ; no-op on ARMv2
AND Rd, Rd, #0xF0000000 ; if want
MOV Rd, #0
ORRVS Rd, Rd, #0x10000000
ORRCS Rd, Rd, #0x20000000
ORREQ Rd, Rd, #0x40000000
ORRMI Rd, Rd, #0x80000000
SBC Rd, Rd, Rd
EORVS Rd, Rd, #0x10000000
EOREQ Rd, Rd, #0x40000000
EORMI Rd, Rd, #0x80000000
; Result: encodes flags non-trivially
; Precondition: Ru=0
ADC Rd, Ru, #0
ORRVS Rd, Rd, #0x80000000
ORREQ Rd, Rd, #2
ORRMI Rd, Rd, #4
; Result: flags rotated left 3
|
MOV Rd, PC
AND Rd, Rd, #0xF0000000 ; if want
EOR Rd, PC, PC ; or RSB
; Note: includes mode+interrupt flags
MOV Rd, PC LSR 28
; Result: flags rotated left 4
|
MRS Rd, CPSR
AND Rd, Rd, #0xF0000000 ; if want
|
Assign V/C/N |
CMN Rn, Rn
; Result: N=Rn30, Z=[Rn=0 or 1<<31], C=Rn31, V=Rn31⊕Rn30
RSBS Rn, Rn, Rn LSL #1
; Result: N=Rn31, Z=[Rn=0], C=Rn31, V=Rn31⊕Rn30
|
|
|
Assign V |
CMN Rn, #0x80000000
; Result: N=Rn31, Z=[Rn=1<<31], C=Rn31, V=Rn31
CMP Rn, #0x80000000
; Result: N=Rn31, Z=[Rn=1<<31], C=Rn31, V=Rn31
|
|
|
Set V |
; Precondition: Rn31=0
CMP Rn, #0x80000000
; Result: NzcV
; Precondition: Rn31=1
CMN Rn, #0x80000000
; Result: n, Z=[Rn=1<<31], CV
CMP Rn, #0x80000000
CMNVC Rn, #0x80000000
; Result: N=Rn31, Z=[Rn=1<<31], C=Rn31, V
CMP PC, #0x80000000
MSR CPSR_f, #0x90000000 ; no-op on ARMv2
; Result: NzcV
|
CMP PC, #0x80000000
; Result: NzcV
; Precondition: Rd=0x10000000
TEQVCP Rd, PC
; Result: V
; Precondition: Rd available
MOV Rd, PC
TEQVCP Rd, #0x10000000
; Result: V
; Precondition: Rd available
MOV Rd, PC
ORRS PC, Rd, #0x10000000
; Result: V
|
; Precondition: Rd available
MRS Rd, CPSR
ORR Rd, Rd, #0x10000000
MSR CPSR_f, Rd
; Result: V
|
Clear V |
CMN Rn, #0
; Result: N=Rn31, Z=[Rn=0], cv
CMP Rn, #0
; Result: N=Rn31, Z=[Rn=0], Cv
CMP Rn, Rn
; Result: nZCv
|
; Precondition: Rd=0x10000000
TEQVSP Rd, PC
; Result: v
; Precondition: Rn=0xEC000003 or Rn=~0x10000000
TSTP Rn, PC
; Result: v
; Precondition: Rd available
MOV Rd, PC
TSTP Rd, #0xEC000003
; Result: v
; Precondition: Rd available
MOV Rd, PC
BICS PC, Rd, #0x10000000
; Result: v
|
; Precondition: Rd available
MRS Rd, CPSR
BIC Rd, Rd, #0x10000000
MSR CPSR_f, Rd
; Result: v
|
Assign C |
|
|
|
Set C |
TST Rn, #0x80000000
; Result: N=Rn31, Z=Rn31, C
TEQ Rn, #0x80000000
; Result: N=Rn31, Z=Rn31, C
CMP Rn, Rn
; Result: nZCv
CMP Rn, #0
; Result: N=Rn31, Z=[Rn=0], Cv
| |
|
Clear C |
TST Rn, #0, 2
; Result: nZc
TEQ Rn, #0, 2
; Result: N=Rn31, Z=Rn31, c
CMN Rn, #0
; Result: N=Rn31, Z=[Rn=0], cv
|
|
|
Assign Z |
|
|
|
Set Z |
|
|
|
Clear Z |
|
|
|
Assign N |
|
|
|
Set N |
|
|
|
Clear N |
|
|
|