P-Code optimizations: Let be oPUSH|oPUSHB Let be oLOD|oLODB|PUSH|oLADR|oLCADR pcopt.c:unaryOptimize STEP 1: Remove unary operators on constants: arg + oNEG -> arg arg + oABS -> |arg| arg + oINC -> arg+1 arg + oDEC -> arg-1 arg + oNOT -> ~arg Simplify binary operations on constants arg + oADD if arg == 0 -> delete both else if arg == 1 -> oINC else if arg == -1 -> oDEC arg + oSUB if arg == 0 -> delete both else if arg == 1 -> oDEC else if arg == -1 -> oINC arg + oMUL if arg is power of 2 -> oSLL power arg + oDIV if arg is power of 2 -> oSRA power arg + oSLL if arg is 0 -> arg arg + oSRL if arg is 0 -> arg arg + oSRA if arg is 0 -> arg arg + oOR if arg is 0 -> arg arg + oAND if arg is 0xffff -> arg Delete comparisons with zero arg + oEQUZ if arg == 0 -> true else -> false arg + oNEQZ if arg != 0 -> true else -> false arg + oLTZ if arg < 0 -> true else -> false arg + oGTEZ if arg >= 0 -> true else -> false arg + oGTZ if arg > 0 -> true else -> false arg + oLTEZ if arg <= 0 -> true else -> false Simplify comparisons with certain constants arg + oEQU if arg == 0 -> oEQUZ else if arg == 1 -> oDEC + oEQUZ else if arg == -1 -> oINC + oEQUZ arg + oNEQ if arg == 0 -> oNEQZ else if arg == 1 -> oDEC + oNEQZ else if arg == -1 -> oINC + oNEQZ arg + oLT if arg == 0 -> oLTZ else if arg == 1 -> oDEC + oLTZ else if arg == -1 -> oINC + oLTZ arg + oGTE if arg == 0 -> oGTEZ else if arg == 1 -> oDEC + oGTEZ else if arg == -1 -> oINC + oGTEZ arg + oGT if arg == 0 -> oGTZ else if arg == 1 -> oDEC + oGTZ else if arg == -1 -> oINC + oGTZ 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 arg + oJEQUZ if arg == 0 -> oJMP else -> delete both arg + oJNEQZ if arg != 0 -> oJMP else -> delete both arg + oJLTZ if arg < 0 -> oJMP else -> delete both arg + oJGTEZ if arg >= 0 -> oJMP else -> delete both arg + oJGTZ if arg > 0 -> oJMP else -> delete both arg + oJLTEZ if arg <= 0 -> oJMP else -> delete both STEP 1a: 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: arg1 + arg2 + oADD -> oPUSH arg1 + arg2 + STEP 1a arg1 + arg2 + oSUB -> oPUSH arg1 - arg2 + STEP 1a arg1 + arg2 + oMUL -> oPUSH arg1 * arg2 + STEP 1a arg1 + arg2 + oDIV -> oPUSH arg1 / arg2 + STEP 1a arg1 + arg2 + oMOD -> oPUSH arg1 % arg2 + STEP 1a arg1 + arg2 + oSLL -> oPUSH arg1 << arg2 + STEP 1a arg1 + arg2 + oSRL -> oPUSH arg1 >> arg2 + STEP 1a arg1 + arg2 + oSRA -> oPUSH arg1 >> arg2 + STEP 1a arg1 + arg2 + oOR -> oPUSH arg1 | arg2 + STEP 1a arg1 + arg2 + oAND -> oPUSH arg1 & arg2 + STEP 1a arg1 + arg2 + oEQU -> oPUSH arg1 == arg2 + STEP 1a arg1 + arg2 + oNEQ -> oPUSH arg1 != arg2 + STEP 1a arg1 + arg2 + oLT -> oPUSH arg1 < arg2 + STEP 1a arg1 + arg2 + oGTE -> oPUSH arg1 >= arg2 + STEP 1a arg1 + arg2 + oGT -> oPUSH arg1 > arg2 + STEP 1a arg1 + arg2 + oLTE -> oPUSH arg1 <= arg2 + STEP 1a STEP 1a: arg if arg < 256 -> oPUSHB arg else -> oPUSH arg STEP 2: arg1 + arg2 + oADD if arg1 == 0 -> arg else if arg1 == 1 -> arg + oINC else if arg1 == -1 -> arg + oDEC arg1 + arg2 + oSUB if arg1 == 0 -> arg + oNEG arg1 + arg2 + oMUL -> arg + oSLL log if arg is a power of 2 arg1 + arg2 + oOR if arg1 == 0 -> arg arg1 + arg2 + oAND if arg1 == 0xffff -> arg arg1 + arg2 + oEQU if arg1 == 0 -> arg + oEQUZ arg1 + arg2 + oNEQ if arg1 == 0 -> arg + oNEQZ arg1 + arg2 + oLT if arg1 == 0 -> arg + oLTZ arg1 + arg2 + oGTE if arg1 == 0 -> arg + oGTEZ arg1 + arg2 + oGT if arg1 == 0 -> arg + oGTZ arg1 + arg2 + oLTE if arg1 == 0 -> arg + oLTEZ STEP 2a: if the op is still there 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 !!! arg1 + oLODX arg2 -> oLOD arg1 + arg2 arg1 + oLADRX arg2 -> oLADR arg1 + arg2 arg1 + oLODBX arg2 -> oLODB arg1 + arg2 arg1 + oLODMX arg2 -> oLODM arg1 + arg2 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 arg1 + ? + oSTOX arg2 -> ? + oSTO arg1 + arg2 arg1 + ? + oSTOBX arg2 -> ? + oSTOB arg1 + arg2 Missing local optimization: Need to check for branches (conditional or unconditional) to the next instruction.