QbeGen.def 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. DEFINITION MODULE QbeGen;
  2. (* QBE backend for the scalar subset of SimpleMod2 (see SimpleQ.atg).
  3. Emits QBE SSA text to "gen_qbe/<Module>.ssa" (directory "gen_qbe"
  4. must exist). Supported: scalar globals of INTEGER / CARDINAL /
  5. SHORTINT / LONGINT / BOOLEAN / CHAR (QBE "w") and REAL / LONGREAL
  6. (QBE "d", i.e. REAL is widened to double), enumeration types with
  7. ordinal values, CONST initializers that are plain literals, full
  8. scalar expressions, and IF / CASE / WHILE / REPEAT / LOOP+EXIT /
  9. FOR statements.
  10. Anything else (ARRAY / RECORD / SET / POINTER values, string
  11. variables, WITH, IN, set literals, non-literal CONST expressions
  12. or BY steps, EXIT outside LOOP, use of imported names as values)
  13. is reported by the parser with error 230; this module only emits
  14. structurally valid placeholder code for those cases.
  15. Test convention: if the source declares a global
  16. VAR ExitCode : INTEGER;
  17. the generated "main" returns its value as the process exit code,
  18. otherwise it returns 0. This makes compiled programs observable
  19. (the language itself has no I/O). *)
  20. TYPE
  21. QVal = ARRAY [0 .. 63] OF CHAR;
  22. (* A QBE operand: either an immediate ("42", "-5", "d_3.14") or a
  23. temporary ("%t7"). Labels ("@L3") travel in plain strings. *)
  24. PROCEDURE OpenModule (name: ARRAY OF CHAR);
  25. (* Opens gen_qbe/<name>.ssa, resets counters. *)
  26. PROCEDURE DeclVar (name: ARRAY OF CHAR; t: INTEGER);
  27. (* Emits "data $name = ..." (w for scalars, d for REAL). The second
  28. parameter is a SymTab.TypeIndex; other classes get a "w 0"
  29. placeholder so the file stays assembleable. *)
  30. PROCEDURE DeclConst (name: ARRAY OF CHAR; val: ARRAY OF CHAR; t: INTEGER);
  31. (* Like DeclVar but initialized from the literal text val
  32. ("100", "-5", "d_3.14"); non-literal val gives a 0 placeholder.
  33. NOTE: this qbe accepts only integer literals in "data", so a
  34. non-zero REAL initializer is emitted as "d 0" plus a runtime copy
  35. at function start (see BeginBody). *)
  36. PROCEDURE BeginBody;
  37. (* Emits "export function w $main() {@start" (once). *)
  38. PROCEDURE EndModule;
  39. (* Emits the return sequence (via ExitCode when present), closes the
  40. function and the file. *)
  41. PROCEDURE NewTemp (VAR t: QVal);
  42. (* Fresh "%tN" operand. *)
  43. PROCEDURE NewLabel (VAR l: QVal);
  44. (* Fresh "@LN" label. *)
  45. PROCEDURE EmitLabel (l: ARRAY OF CHAR);
  46. PROCEDURE Jmp (l: ARRAY OF CHAR);
  47. PROCEDURE Jnz (c, t, f: ARRAY OF CHAR);
  48. (* "jnz c, @t, @f". *)
  49. PROCEDURE LoadVar (name: ARRAY OF CHAR; isReal: BOOLEAN; VAR q: QVal);
  50. (* q := fresh temp holding $name. *)
  51. PROCEDURE StoreVar (name: ARRAY OF CHAR; q: ARRAY OF CHAR; isReal: BOOLEAN);
  52. (* "storew/stored q, $name". *)
  53. PROCEDURE Op3 (mn: ARRAY OF CHAR; res, l, r: ARRAY OF CHAR;
  54. isReal: BOOLEAN);
  55. (* "res =w/=d mn l, r". *)
  56. PROCEDURE Cmp (op: INTEGER; l, r: ARRAY OF CHAR; VAR q: QVal;
  57. isReal: BOOLEAN);
  58. (* Signed integer (ceqw/cnew/csltw/...) or double (ceqd/.../cled/...)
  59. comparison selected by a SymTab.OpEq..OpGe code; q := fresh w. *)
  60. PROCEDURE NegQ (a: ARRAY OF CHAR; VAR q: QVal; isReal: BOOLEAN);
  61. (* q := fresh temp holding "-a" (sub from 0). *)
  62. PROCEDURE NotQ (a: ARRAY OF CHAR; VAR q: QVal);
  63. (* q := fresh temp holding "NOT a" (xor 1, a). *)
  64. PROCEDURE ConvIR (a: ARRAY OF CHAR; VAR q: QVal);
  65. (* q := fresh double holding "swtof a" (INTEGER -> REAL). *)
  66. PROCEDURE CopyOp (s: ARRAY OF CHAR; VAR d: ARRAY OF CHAR);
  67. PROCEDURE IntStr (v: INTEGER; VAR s: QVal);
  68. PROCEDURE NormInt (s: ARRAY OF CHAR; VAR d: QVal);
  69. (* "123" -> "123"; "0FFH" -> "255". *)
  70. PROCEDURE NormReal (s: ARRAY OF CHAR; VAR d: QVal);
  71. (* "3.14" -> "d_3.14" (QBE double immediates carry a d_ prefix). *)
  72. PROCEDURE CharVal (s: ARRAY OF CHAR): INTEGER;
  73. (* ORD of a 1-character literal such as 'a'. *)
  74. PROCEDURE NegFold (a: ARRAY OF CHAR; VAR q: QVal);
  75. (* Folds a unary minus into a literal operand ("5" -> "-5"). *)
  76. PROCEDURE IsImm (s: ARRAY OF CHAR): BOOLEAN;
  77. (* TRUE for literal operands (not %temporaries). *)
  78. PROCEDURE IsNeg (s: ARRAY OF CHAR): BOOLEAN;
  79. (* TRUE for a leading '-'. *)
  80. PROCEDURE PushLoop (exit: ARRAY OF CHAR);
  81. PROCEDURE PopLoop;
  82. PROCEDURE TopLoop (VAR exit: QVal): BOOLEAN;
  83. (* Innermost LOOP exit label; FALSE when outside any LOOP. *)
  84. PROCEDURE NoQbeEnter;
  85. PROCEDURE NoQbeExit;
  86. PROCEDURE NoQbe (): BOOLEAN;
  87. (* Guard depth for unsupported constructs: while > 0 the grammar
  88. suppresses follow-on 230 errors to avoid cascades. *)
  89. PROCEDURE Remark (s: ARRAY OF CHAR);
  90. (* Emits a "# s" comment line. *)
  91. END QbeGen.