| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
- program t35;
- { t35 -- `not', on both of the operand types it is defined for.
- TPSRC9 neglevel picks the instruction from the operand's type before it
- emits anything:
- CMP.B CL,#$0A ; integer ?
- JZ negnot ; -> CALL loadatom ; NOT AX (F7 D0)
- CMP.B CL,#$0B ; boolean ?
- CALL errnz ; -> error 47 for anything else
- CALL loadatom
- ; -> XOR AL,#01 (34 01)
- This compiler used to emit NOT AX for both of them, so every boolean
- came out wrong one way: `not (a = a)' computed 0FFFEh and the runtime's
- wrbool tests [BP+4] <> 0, which reads 0FFFEh as TRUE. Pascal says
- FALSE. Exec86 and qemu agreed with each other and both disagreed with
- Pascal, which is what pins the fault on the compiler and not on the
- interpreter.
- The integer half is here because it is the other arm of the same branch:
- `not a' has to stay NOT AX, and must not be dragged along to XOR AL,#01
- by a fix aimed at booleans.
- A BOOLEAN variable is one byte and LoadAtom clears AH after a byte load,
- so XOR AL,#01 cannot leave a dirty high byte for wrbool to trip over.
- Every expectation below is derived from Pascal's definition - `not' on an
- integer is the 16-bit one's complement, `not' on a boolean is logical
- negation - and from nowhere else. }
- var
- a : integer;
- b : boolean;
- begin
- a := 17;
- writeln (not a);
- writeln (not (a = 17));
- writeln (not (a = 18));
- writeln (not (a > 100));
- b := a = 17;
- writeln (not b);
- b := a = 18;
- writeln (not b);
- writeln (not 5)
- end.
|