Assign all flags 
; Precondition: usermode, or known PSR;
; also PSR nonzero  can precede with
; TEQ R0, R0 if not
TEQ PC, PC
TEQNEP PC, #0x??00000?
MSR CPSR_f, #0x?0000000 ; noop 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 ; noop 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: usermode, 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 ; noop 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 nontrivially
; 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=Rn_{30}, Z=[Rn=0 or 1<<31], C=Rn_{31}, V=Rn_{31}⊕Rn_{30}
RSBS Rn, Rn, Rn LSL #1
; Result: N=Rn_{31}, Z=[Rn=0], C=Rn_{31}, V=Rn_{31}⊕Rn_{30}



Assign V 
CMN Rn, #0x80000000
; Result: N=Rn_{31}, Z=[Rn=1<<31], C=Rn_{31}, V=Rn_{31}
CMP Rn, #0x80000000
; Result: N=Rn_{31}, Z=[Rn=1<<31], C=Rn_{31}, V=Rn_{31}



Set V 
; Precondition: Rn_{31}=0
CMP Rn, #0x80000000
; Result: NzcV
; Precondition: Rn_{31}=1
CMN Rn, #0x80000000
; Result: n, Z=[Rn=1<<31], CV
CMP Rn, #0x80000000
CMNVC Rn, #0x80000000
; Result: N=Rn_{31}, Z=[Rn=1<<31], C=Rn_{31}, V
CMP PC, #0x80000000
MSR CPSR_f, #0x90000000 ; noop 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=Rn_{31}, Z=[Rn=0], cv
CMP Rn, #0
; Result: N=Rn_{31}, 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=Rn_{31}, Z=Rn_{31}, C
TEQ Rn, #0x80000000
; Result: N=Rn_{31}, Z=Rn_{31}, C
CMP Rn, Rn
; Result: nZCv
CMP Rn, #0
; Result: N=Rn_{31}, Z=[Rn=0], Cv
 

Clear C 
TST Rn, #0, 2
; Result: nZc
TEQ Rn, #0, 2
; Result: N=Rn_{31}, Z=Rn_{31}, c
CMN Rn, #0
; Result: N=Rn_{31}, Z=[Rn=0], cv



Assign Z 



Set Z 



Clear Z 



Assign N 



Set N 



Clear N 


