Borland Turbo Pascal permits AND, OR and XOR operations for many compatible types.
This is the beginning of code generation for OR and XOR.
For operations with two variables, OR and XOR are very similar.
Of particular interest is the first assignment. Unlike addition and subtraction, ORing and XORing extended signs never accumulate or cancel. It is sufficient to determine the result of operating on the two bytes and sign extend that.
Code:
00320 ; 00013 W0 := S1 or S2;
0106 D6 36 [3] 00321 ldab S1
0108 DA 3A [3] 00322 orab S2
010A 86 7F [2] 00323 ldaa #$7F ; Thanks Mike B!
010C 11 [2] 00324 cba
010D 82 7F [2] 00325 sbca #$7F
010F 97 38 [4] 00326 staa W0
0111 D7 39 [4] 00327 stab W0+1
00328 ; 00014 W0 := W1 or S2;
0113 D6 3A [3] 00329 ldab S2
0115 86 7F [2] 00330 ldaa #$7F ; Thanks Mike B!
0117 11 [2] 00331 cba
0118 82 7F [2] 00332 sbca #$7F
011A DA 35 [3] 00333 orab W1+1
011C 9A 34 [3] 00334 oraa W1
011E 97 38 [4] 00335 staa W0
0120 D7 39 [4] 00336 stab W0+1
00337 ; 00015 W0 := S1 or W2;
0122 D6 36 [3] 00338 ldab S1
0124 86 7F [2] 00339 ldaa #$7F ; Thanks Mike B!
0126 11 [2] 00340 cba
0127 82 7F [2] 00341 sbca #$7F
0129 DA 41 [3] 00342 orab W2+1
012B 9A 40 [3] 00343 oraa W2
012D 97 38 [4] 00344 staa W0
012F D7 39 [4] 00345 stab W0+1
00346 ; 00016 W0 := B1 or B2;
0131 D6 18 [3] 00347 ldab B1
0133 DA 1A [3] 00348 orab B2
0135 4F [2] 00349 clra
0136 97 38 [4] 00350 staa W0
0138 D7 39 [4] 00351 stab W0+1
00352 ; 00017 W0 := W1 or B2;
013A D6 35 [3] 00353 ldab W1+1
013C DA 1A [3] 00354 orab B2
013E 96 34 [3] 00355 ldaa W1
0140 97 38 [4] 00356 staa W0
0142 D7 39 [4] 00357 stab W0+1
00358 ; 00018 W0 := B1 or W2;
0144 D6 18 [3] 00359 ldab B1
0146 DA 41 [3] 00360 orab W2+1
0148 96 40 [3] 00361 ldaa W2
014A 97 38 [4] 00362 staa W0
014C D7 39 [4] 00363 stab W0+1
00364 ; 00019 W0 := W1 or W2;
014E D6 35 [3] 00365 ldab W1+1
0150 DA 41 [3] 00366 orab W2+1
0152 96 34 [3] 00367 ldaa W1
0154 9A 40 [3] 00368 oraa W2
0156 97 38 [4] 00369 staa W0
0158 D7 39 [4] 00370 stab W0+1
00371 ; 00020 B0 := B1 or B2;
015A 96 18 [3] 00372 ldaa B1
015C 9A 1A [3] 00373 oraa B2
015E 97 16 [4] 00374 staa B0
00375 ; 00021 W0 := S1 xor S2;
0160 D6 36 [3] 00376 ldab S1
0162 D8 3A [3] 00377 eorb S2
0164 86 7F [2] 00378 ldaa #$7F ; Thanks Mike B!
0166 11 [2] 00379 cba
0167 82 7F [2] 00380 sbca #$7F
0169 97 38 [4] 00381 staa W0
016B D7 39 [4] 00382 stab W0+1
The depessimizer needed a little bit of adjustment.
B1 or B3 - B1 is not necessarily the same as B3.
Code:
00320 ; 00013 B0 := B1 or B3 - B1;
00321 * * 0 := v B0 -> 1
00322 * * 1 L r 2
00323
00324 * * 2 L v B1 -> 3
00325 * * 3 | v B3 -> 4
00326 * * 4 - v B1
00327 * 1 L r 2
00328 * 2 L v B1 -> 3
00329 * 3 | v B3 -> 4
0106 96 18 [3] 00330 ldaa B1
0108 9A 1C [3] 00331 oraa B3
00332 * 4 - v B1
010A 90 18 [3] 00333 suba B1
00334 * 0 := v B0 -> 1
010C 97 16 [4] 00335 staa B0
However, variables in subexpressions on either side of an OR operation are allowed to cancel out:
Code:
00337 ; 00014 B0 := B2 + B1 - B2 or B3 + B1 + B2 - B1;
00338 * * 0 := v B0 -> 1
00339 * * 1 L r 2
00340
00341 * * 2 L v B2 -> 3
00342 * * 3 + v B1 -> 4
00343 * * 4 - v B2 -> 5
00344 * * 5 | v B3 -> 6
00345 * * 6 + v B1 -> 7
00346 * * 7 + v B2 -> 8
00347 * * 8 - v B1
00348 * delete * 4 - v B2 -> 5
00349 * change * 2 L c 0 -> 3
00350 * delete * 8 - v B1
00351 * change * 6 + c 0 -> 7
00352 * delete * 6 + c 0 -> 7
00353 * merge * 3 + v B1 -> 5
00354
00355 * * 0 := v B0 -> 1
00356 * * 1 L r 2
00357
00358 * * 2 L v B1 -> 5
00359 * * 5 | v B3 -> 7
00360 * * 7 + v B2
00361
00362
00363 * 1 L r 2
00364 * 2 L v B1 -> 5
00365 * 5 | v B3 -> 7
0110 96 18 [3] 00366 ldaa B1
0112 9A 1C [3] 00367 oraa B3
00368 * 7 + v B2
0114 DB 1A [3] 00369 addb B2
00370 * 0 := v B0 -> 1
0116 97 16 [4] 00371 staa B0
Next up is generating code to OR and XOR a variable with a constant. This will present many opportunities to save a few cycles or bytes here and there.
Edit: Found and fixed a bug in B0 := B1 or B3 - B1 example