| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- DEFINITION MODULE QbeGen;
- (* QBE backend for the scalar subset of SimpleMod2 (see SimpleQ.atg).
- Emits QBE SSA text to "gen_qbe/<Module>.ssa" (directory "gen_qbe"
- must exist). Supported: scalar globals of INTEGER / CARDINAL /
- SHORTINT / LONGINT / BOOLEAN / CHAR (QBE "w") and REAL / LONGREAL
- (QBE "d", i.e. REAL is widened to double), enumeration types with
- ordinal values, CONST initializers that are plain literals, full
- scalar expressions, and IF / CASE / WHILE / REPEAT / LOOP+EXIT /
- FOR statements.
- Anything else (ARRAY / RECORD / SET / POINTER values, string
- variables, WITH, IN, set literals, non-literal CONST expressions
- or BY steps, EXIT outside LOOP, use of imported names as values)
- is reported by the parser with error 230; this module only emits
- structurally valid placeholder code for those cases.
- Test convention: if the source declares a global
- VAR ExitCode : INTEGER;
- the generated "main" returns its value as the process exit code,
- otherwise it returns 0. This makes compiled programs observable
- (the language itself has no I/O). *)
- TYPE
- QVal = ARRAY [0 .. 63] OF CHAR;
- (* A QBE operand: either an immediate ("42", "-5", "d_3.14") or a
- temporary ("%t7"). Labels ("@L3") travel in plain strings. *)
- PROCEDURE OpenModule (name: ARRAY OF CHAR);
- (* Opens gen_qbe/<name>.ssa, resets counters. *)
- PROCEDURE DeclVar (name: ARRAY OF CHAR; t: INTEGER);
- (* Emits "data $name = ..." (w for scalars, d for REAL). The second
- parameter is a SymTab.TypeIndex; other classes get a "w 0"
- placeholder so the file stays assembleable. *)
- PROCEDURE DeclConst (name: ARRAY OF CHAR; val: ARRAY OF CHAR; t: INTEGER);
- (* Like DeclVar but initialized from the literal text val
- ("100", "-5", "d_3.14"); non-literal val gives a 0 placeholder.
- NOTE: this qbe accepts only integer literals in "data", so a
- non-zero REAL initializer is emitted as "d 0" plus a runtime copy
- at function start (see BeginBody). *)
- PROCEDURE BeginBody;
- (* Emits "export function w $main() {@start" (once). *)
- PROCEDURE EndModule;
- (* Emits the return sequence (via ExitCode when present), closes the
- function and the file. *)
- PROCEDURE NewTemp (VAR t: QVal);
- (* Fresh "%tN" operand. *)
- PROCEDURE NewLabel (VAR l: QVal);
- (* Fresh "@LN" label. *)
- PROCEDURE EmitLabel (l: ARRAY OF CHAR);
- PROCEDURE Jmp (l: ARRAY OF CHAR);
- PROCEDURE Jnz (c, t, f: ARRAY OF CHAR);
- (* "jnz c, @t, @f". *)
- PROCEDURE LoadVar (name: ARRAY OF CHAR; isReal: BOOLEAN; VAR q: QVal);
- (* q := fresh temp holding $name. *)
- PROCEDURE StoreVar (name: ARRAY OF CHAR; q: ARRAY OF CHAR; isReal: BOOLEAN);
- (* "storew/stored q, $name". *)
- PROCEDURE Op3 (mn: ARRAY OF CHAR; res, l, r: ARRAY OF CHAR;
- isReal: BOOLEAN);
- (* "res =w/=d mn l, r". *)
- PROCEDURE Cmp (op: INTEGER; l, r: ARRAY OF CHAR; VAR q: QVal;
- isReal: BOOLEAN);
- (* Signed integer (ceqw/cnew/csltw/...) or double (ceqd/.../cled/...)
- comparison selected by a SymTab.OpEq..OpGe code; q := fresh w. *)
- PROCEDURE NegQ (a: ARRAY OF CHAR; VAR q: QVal; isReal: BOOLEAN);
- (* q := fresh temp holding "-a" (sub from 0). *)
- PROCEDURE NotQ (a: ARRAY OF CHAR; VAR q: QVal);
- (* q := fresh temp holding "NOT a" (xor 1, a). *)
- PROCEDURE ConvIR (a: ARRAY OF CHAR; VAR q: QVal);
- (* q := fresh double holding "swtof a" (INTEGER -> REAL). *)
- PROCEDURE CopyOp (s: ARRAY OF CHAR; VAR d: ARRAY OF CHAR);
- PROCEDURE IntStr (v: INTEGER; VAR s: QVal);
- PROCEDURE NormInt (s: ARRAY OF CHAR; VAR d: QVal);
- (* "123" -> "123"; "0FFH" -> "255". *)
- PROCEDURE NormReal (s: ARRAY OF CHAR; VAR d: QVal);
- (* "3.14" -> "d_3.14" (QBE double immediates carry a d_ prefix). *)
- PROCEDURE CharVal (s: ARRAY OF CHAR): INTEGER;
- (* ORD of a 1-character literal such as 'a'. *)
- PROCEDURE NegFold (a: ARRAY OF CHAR; VAR q: QVal);
- (* Folds a unary minus into a literal operand ("5" -> "-5"). *)
- PROCEDURE IsImm (s: ARRAY OF CHAR): BOOLEAN;
- (* TRUE for literal operands (not %temporaries). *)
- PROCEDURE IsNeg (s: ARRAY OF CHAR): BOOLEAN;
- (* TRUE for a leading '-'. *)
- PROCEDURE PushLoop (exit: ARRAY OF CHAR);
- PROCEDURE PopLoop;
- PROCEDURE TopLoop (VAR exit: QVal): BOOLEAN;
- (* Innermost LOOP exit label; FALSE when outside any LOOP. *)
- PROCEDURE NoQbeEnter;
- PROCEDURE NoQbeExit;
- PROCEDURE NoQbe (): BOOLEAN;
- (* Guard depth for unsupported constructs: while > 0 the grammar
- suppresses follow-on 230 errors to avoid cascades. *)
- PROCEDURE Remark (s: ARRAY OF CHAR);
- (* Emits a "# s" comment line. *)
- END QbeGen.
|