px4-firmware/misc/pascal/insn16/doc/PascalOptimizations.txt

240 lines
11 KiB
Plaintext

P-Code optimizations:
Let <push-ops> be oPUSH|oPUSHB
Let <load-ops> be oLOD|oLODB|PUSH|oLADR|oLCADR
pcopt.c:unaryOptimize
STEP 1:
Remove unary operators on constants:
<push-op> arg + oNEG -> <push-op> arg
<push-op> arg + oABS -> <push-op> |arg|
<push-op> arg + oINC -> <push-op> arg+1
<push-op> arg + oDEC -> <push-op> arg-1
<push-op> arg + oNOT -> <push-op> ~arg
Simplify binary operations on constants
<push-op> arg + oADD
if arg == 0 -> delete both
else if arg == 1 -> oINC
else if arg == -1 -> oDEC
<push-op> arg + oSUB
if arg == 0 -> delete both
else if arg == 1 -> oDEC
else if arg == -1 -> oINC
<push-op> arg + oMUL
if arg is power of 2 -> oSLL power
<push-op> arg + oDIV
if arg is power of 2 -> oSRA power
<push-op> arg + oSLL
if arg is 0 -> <push-op> arg
<push-op> arg + oSRL
if arg is 0 -> <push-op> arg
<push-op> arg + oSRA
if arg is 0 -> <push-op> arg
<push-op> arg + oOR
if arg is 0 -> <push-op> arg
<push-op> arg + oAND
if arg is 0xffff -> <push-op> arg
Delete comparisons with zero
<push-op> arg + oEQUZ
if arg == 0 -> <push-op> true
else -> <push-op> false
<push-op> arg + oNEQZ
if arg != 0 -> <push-op> true
else -> <push-op> false
<push-op> arg + oLTZ
if arg < 0 -> <push-op> true
else -> <push-op> false
<push-op> arg + oGTEZ
if arg >= 0 -> <push-op> true
else -> <push-op> false
<push-op> arg + oGTZ
if arg > 0 -> <push-op> true
else -> <push-op> false
<push-op> arg + oLTEZ
if arg <= 0 -> <push-op> true
else -> <push-op> false
Simplify comparisons with certain constants
<push-op> arg + oEQU
if arg == 0 -> oEQUZ
else if arg == 1 -> oDEC + oEQUZ
else if arg == -1 -> oINC + oEQUZ
<push-op> arg + oNEQ
if arg == 0 -> oNEQZ
else if arg == 1 -> oDEC + oNEQZ
else if arg == -1 -> oINC + oNEQZ
<push-op> arg + oLT
if arg == 0 -> oLTZ
else if arg == 1 -> oDEC + oLTZ
else if arg == -1 -> oINC + oLTZ
<push-op> arg + oGTE
if arg == 0 -> oGTEZ
else if arg == 1 -> oDEC + oGTEZ
else if arg == -1 -> oINC + oGTEZ
<push-op> arg + oGT
if arg == 0 -> oGTZ
else if arg == 1 -> oDEC + oGTZ
else if arg == -1 -> oINC + oGTZ
<push-op> arg + oLTE
if arg == 0 -> oLTEZ
else if arg == 1 -> oDEC + oLTEZ
else if arg == -1 -> oINC + oLTEZ
Simplify or delete condition branches on constants
<push-op> arg + oJEQUZ
if arg == 0 -> oJMP
else -> delete both
<push-op> arg + oJNEQZ
if arg != 0 -> oJMP
else -> delete both
<push-op> arg + oJLTZ
if arg < 0 -> oJMP
else -> delete both
<push-op> arg + oJGTEZ
if arg >= 0 -> oJMP
else -> delete both
<push-op> arg + oJGTZ
if arg > 0 -> oJMP
else -> delete both
<push-op> arg + oJLTEZ
if arg <= 0 -> oJMP
else -> delete both
STEP 1a:
<push-op> arg
if arg < 256 -> oPUSHB arg
else -> oPUSH arg
STEP 2:
Delete multiple modifications of DSEG pointer
INDS arg1 + INDS arg2 -> INDS arg1+arg2
pcopt.c:binaryOptimize
STEP 1:
<push-op> arg1 + <push-op> arg2 + oADD -> oPUSH arg1 + arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oSUB -> oPUSH arg1 - arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oMUL -> oPUSH arg1 * arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oDIV -> oPUSH arg1 / arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oMOD -> oPUSH arg1 % arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oSLL -> oPUSH arg1 << arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oSRL -> oPUSH arg1 >> arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oSRA -> oPUSH arg1 >> arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oOR -> oPUSH arg1 | arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oAND -> oPUSH arg1 & arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oEQU -> oPUSH arg1 == arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oNEQ -> oPUSH arg1 != arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oLT -> oPUSH arg1 < arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oGTE -> oPUSH arg1 >= arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oGT -> oPUSH arg1 > arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oLTE -> oPUSH arg1 <= arg2 + STEP 1a
STEP 1a:
<push-op> arg
if arg < 256 -> oPUSHB arg
else -> oPUSH arg
STEP 2:
<push-op> arg1 + <load-ops> arg2 + oADD
if arg1 == 0 -> <load-ops> arg
else if arg1 == 1 -> <load-ops> arg + oINC
else if arg1 == -1 -> <load-ops> arg + oDEC
<push-op> arg1 + <load-ops> arg2 + oSUB
if arg1 == 0 -> <load-ops> arg + oNEG
<push-op> arg1 + <load-ops> arg2 + oMUL -> <load-ops> arg + oSLL log
if arg is a power of 2
<push-op> arg1 + <load-ops> arg2 + oOR
if arg1 == 0 -> <load-ops> arg
<push-op> arg1 + <load-ops> arg2 + oAND
if arg1 == 0xffff -> <load-ops> arg
<push-op> arg1 + <load-ops> arg2 + oEQU
if arg1 == 0 -> <load-ops> arg + oEQUZ
<push-op> arg1 + <load-ops> arg2 + oNEQ
if arg1 == 0 -> <load-ops> arg + oNEQZ
<push-op> arg1 + <load-ops> arg2 + oLT
if arg1 == 0 -> <load-ops> arg + oLTZ
<push-op> arg1 + <load-ops> arg2 + oGTE
if arg1 == 0 -> <load-ops> arg + oGTEZ
<push-op> arg1 + <load-ops> arg2 + oGT
if arg1 == 0 -> <load-ops> arg + oGTZ
<push-op> arg1 + <load-ops> arg2 + oLTE
if arg1 == 0 -> <load-ops> arg + oLTEZ
STEP 2a:
if the <push-op> op is still there
<push-op> arg
if arg < 256 -> oPUSHB arg
else -> oPUSH arg
STEP 3
oNEG + oADD -> oSUB
oNEG + oSUB -> oADD
pjopt.c: BranchOptimize
oNOT + oJEQUZ -> oJNEQZ
oNOT + oJNEQZ -> oJEQUZ
oNEG + oJLTZ -> oJGTZ
oNEG + oJGTEZ -> oJLTEZ
oNEG + oJGTZ -> oJLTZ
oNEG + oJLTEZ -> oJGTEZ
oEQU + oNOT -> oNEQ
oEQU + oJEQUZ -> oJNEQ
oEQU + oJNEQZ -> oJEQU
oNEQ + oNOT -> oEQU
oNEQ + oJEQUZ -> oJEQU
oNEQ + oJNEQZ -> oJNEQ
oLT + oNOT -> oGTE
oLT + oJEQUZ -> oJGTE
oLT + oJNEQZ -> oJLT
oGTE + oNOT -> oLT
oGTE + oJEQUZ -> oJLT
oGTE + oJNEQZ -> oJGTE
oGT + oNOT -> oLTE
oGT + oJEQUZ -> oJLTE
oGT + oJNEQZ -> oJGT
oLTE + oJNOT -> oGT
oLTE + oJEQUZ -> oJGT
oLTE + oJNEQZ -> oJLTE
oEQUZ + oNOT -> oNEQZ
oEQUZ + oJEQUZ -> oJNEQZ
oEQUZ + oJNEQZ -> oJEQUZ
oNEQZ + oNOT -> oEQUZ
oNEQZ + oJEQUZ -> oJEQUZ
oNEQZ + oJNEQZ -> oJNEQZ
oLTZ + oNOT -> oGTEZ
oLTZ + oJEQUZ -> oJGTEZ
oLTZ + oJNEQZ -> oJLTZ
oGTEZ + oNOT -> oLTZ
oGTEZ + oJEQUZ -> oJLTZ
oGTEZ + oJNEQZ -> oJGTEZ
oGTZ + oNOT -> oLTEZ
oGTZ + oJEQUZ -> oJLTEZ
oGTZ + oJNEQZ -> oJGTZ
oLTEZ + oNOT -> oGTZ
oLTEZ + oJEQUZ -> oJGTZ
oLTEZ + oJNEQZ -> oJLTEZ
plopt.c:LoadOptimize()
Eliminate duplicate loads
oLOD arg1 + oLOAD arg1 -> oLOD arg1 + oDUP
Convert loads indexed by a constant to unindexed loads
!!! DISABLED !!! Does not work because arg2 is a label, not an address !!!
<push-op> arg1 + oLODX arg2 -> oLOD arg1 + arg2
<push-op> arg1 + oLADRX arg2 -> oLADR arg1 + arg2
<push-op> arg1 + oLODBX arg2 -> oLODB arg1 + arg2
<push-op> arg1 + oLODMX arg2 -> oLODM arg1 + arg2
<push-op> arg
if arg < 256 -> oPUSHB arg
plopt.c:StoreOptimize()
Eliminate store followed by load
oSTO arg + oLOAD arg -> oSTO arg + oDUP
Convert stores indexed by a constant to unindexed stores
<push-op> arg1 + ? + oSTOX arg2 -> ? + oSTO arg1 + arg2
<push-op> arg1 + ? + oSTOBX arg2 -> ? + oSTOB arg1 + arg2
Missing local optimization:
Need to check for branches (conditional or unconditional) to the
next instruction.