MODULE--------------------------------------------------------------- parsing ---; IMPORT Text, Rd, IntIntTbl, Thread, Convert, Wr, Stdio, Fmt; IMPORT M3ID, M3CG, M3CG_Ops, Target, TInt, TFloat; FROM M3CG IMPORT CompareOp, ConvertOp, AtomicOp, RuntimeError; FROM M3CG IMPORT MemoryOrder; CONST EOF = '\000'; BufSize = 4096; TYPE InputBuffer = REF ARRAY [0..BufSize-1] OF CHAR; TYPE State = RECORD rd : Rd.T; cg : M3CG.T; ch : CHAR; (* current scan character *) buf : InputBuffer; buf_len: CARDINAL; buf_ptr: CARDINAL; vars : REF ARRAY OF M3CG.Var; procs : REF ARRAY OF M3CG.Proc; labels : REF ARRAY OF M3CG.Label; END; TYPE Cmd = RECORD op : TEXT; proc : PROCEDURE (VAR s: State); END; CONST CmdMap = ARRAY [0..161] OF Cmd { Cmd {"begin_unit", begin_unit}, Cmd {"end_unit", end_unit}, Cmd {"import_unit", import_unit}, Cmd {"export_unit", export_unit}, Cmd {"-----FILE", set_source_file}, Cmd {"-----LINE", set_source_line}, Cmd {"declare_typename", declare_typename}, Cmd {"declare_array", declare_array}, Cmd {"declare_open_array", declare_open_array}, Cmd {"declare_enum", declare_enum}, Cmd {"declare_enum_elt", declare_enum_elt}, Cmd {"declare_packed", declare_packed}, Cmd {"declare_record", declare_record}, Cmd {"declare_field", declare_field}, Cmd {"declare_set", declare_set}, Cmd {"declare_subrange", declare_subrange}, Cmd {"declare_pointer", declare_pointer}, Cmd {"declare_indirect", declare_indirect}, Cmd {"declare_proctype", declare_proctype}, Cmd {"declare_formal", declare_formal}, Cmd {"declare_raises", declare_raises}, Cmd {"declare_object", declare_object}, Cmd {"declare_method", declare_method}, Cmd {"declare_opaque", declare_opaque}, Cmd {"reveal_opaque", reveal_opaque}, Cmd {"declare_exception", declare_exception}, Cmd {"set_runtime_proc", set_runtime_proc}, Cmd {"set_runtime_hook", set_runtime_hook}, Cmd {"get_runtime_hook", get_runtime_hook}, Cmd {"import_global", import_global}, Cmd {"declare_segment", declare_segment}, Cmd {"bind_segment", bind_segment}, Cmd {"declare_global", declare_global}, Cmd {"declare_constant", declare_constant}, Cmd {"declare_local", declare_local}, Cmd {"declare_param", declare_param}, Cmd {"declare_temp", declare_temp}, Cmd {"free_temp", free_temp}, Cmd {"begin_init", begin_init}, Cmd {"end_init", end_init}, Cmd {"init_int", init_int}, Cmd {"init_proc", init_proc}, Cmd {"init_label", init_label}, Cmd {"init_var", init_var}, Cmd {"init_offset", init_offset}, Cmd {"init_chars", init_chars}, Cmd {"init_float", init_float}, Cmd {"import_procedure", import_procedure}, Cmd {"declare_procedure", declare_procedure}, Cmd {"begin_procedure", begin_procedure}, Cmd {"end_procedure", end_procedure}, Cmd {"begin_block", begin_block}, Cmd {"end_block", end_block}, Cmd {"note_procedure_origin", note_procedure_origin}, Cmd {".", set_label}, Cmd {"jump", jump}, Cmd {"if_true", if_true}, Cmd {"if_false", if_false}, Cmd {"if_eq", if_eq}, Cmd {"if_ne", if_ne}, Cmd {"if_gt", if_gt}, Cmd {"if_ge", if_ge}, Cmd {"if_lt", if_lt}, Cmd {"if_le", if_le}, Cmd {"case_jump", case_jump}, Cmd {"exit_proc", exit_proc}, Cmd {"load", load}, Cmd {"store", store}, Cmd {"load_address", load_address}, Cmd {"load_indirect", load_indirect}, Cmd {"store_indirect", store_indirect}, Cmd {"load_nil", load_nil}, Cmd {"load_integer", load_integer}, Cmd {"load_float", load_float}, Cmd {"eq", eq}, Cmd {"ne", ne}, Cmd {"gt", gt}, Cmd {"ge", ge}, Cmd {"lt", lt}, Cmd {"le", le}, Cmd {"add", add}, Cmd {"subtract", subtract}, Cmd {"multiply", multiply}, Cmd {"divide", divide}, Cmd {"div", div}, Cmd {"mod", mod}, Cmd {"negate", negate}, Cmd {"abs", abs}, Cmd {"max", max}, Cmd {"min", min}, Cmd {"round", round}, Cmd {"trunc", trunc}, Cmd {"floor", floor}, Cmd {"ceiling", ceiling}, Cmd {"cvt_float", cvt_float}, Cmd {"set_union", set_union}, Cmd {"set_difference", set_difference}, Cmd {"set_intersection", set_intersection}, Cmd {"set_sym_difference", set_sym_difference}, Cmd {"set_member", set_member}, Cmd {"set_eq", set_eq}, Cmd {"set_ne", set_ne}, Cmd {"set_gt", set_gt}, Cmd {"set_ge", set_ge}, Cmd {"set_lt", set_lt}, Cmd {"set_le", set_le}, Cmd {"set_range", set_range}, Cmd {"set_singleton", set_singleton}, Cmd {"not", not}, Cmd {"and", and}, Cmd {"or", or}, Cmd {"xor", xor}, Cmd {"shift", shift}, Cmd {"shift_left", shift_left}, Cmd {"shift_right", shift_right}, Cmd {"rotate", rotate}, Cmd {"rotate_left", rotate_left}, Cmd {"rotate_right", rotate_right}, Cmd {"widen", widen}, Cmd {"chop", chop}, Cmd {"extract", extract}, Cmd {"extract_n", extract_n}, Cmd {"extract_mn", extract_mn}, Cmd {"insert", insert}, Cmd {"insert_n", insert_n}, Cmd {"insert_mn", insert_mn}, Cmd {"swap", swap}, Cmd {"pop", pop}, Cmd {"copy", copy}, Cmd {"copy_n", copy_n}, Cmd {"zero", zero}, Cmd {"zero_n", zero_n}, Cmd {"loophole", loophole}, Cmd {"abort", abort}, Cmd {"check_nil", check_nil}, Cmd {"check_lo", check_lo}, Cmd {"check_hi", check_hi}, Cmd {"check_range", check_range}, Cmd {"check_index", check_index}, Cmd {"check_eq", check_eq}, Cmd {"add_offset", add_offset}, Cmd {"index_address", index_address}, Cmd {"start_call_direct", start_call_direct}, Cmd {"call_direct", call_direct}, Cmd {"start_call_indirect", start_call_indirect}, Cmd {"call_indirect", call_indirect}, Cmd {"pop_param", pop_param}, Cmd {"pop_struct", pop_struct}, Cmd {"pop_static_link", pop_static_link}, Cmd {"load_procedure", load_procedure}, Cmd {"load_static_link", load_static_link}, Cmd {"#", comment}, Cmd {"store_ordered", store_ordered}, Cmd {"load_ordered", load_ordered}, Cmd {"exchange", exchange}, Cmd {"compare_exchange", compare_exchange}, Cmd {"fence", fence}, Cmd {"fetch_and_add", fetch_and_add}, Cmd {"fetch_and_sub", fetch_and_sub}, Cmd {"fetch_and_or", fetch_and_or}, Cmd {"fetch_and_and", fetch_and_and}, Cmd {"fetch_and_xor", fetch_and_xor} }; VAR cmds: IntIntTbl.T := NIL; types: IntIntTbl.T := NIL; PROCEDURE M3CG_Rd Inhale (rd: Rd.T; cg: M3CG.T) = VAR s: State; op: M3CG.Name; cmd: INTEGER; BEGIN s.rd := rd; s.cg := cg; s.ch := ' '; s.buf := NEW (InputBuffer); s.buf_len := 0; s.buf_ptr := 0; s.vars := NEW (REF ARRAY OF M3CG.Var, 400); s.procs := NEW (REF ARRAY OF M3CG.Proc, 50); s.labels := NEW (REF ARRAY OF M3CG.Label, 400); FOR i := 0 TO LAST(s.labels^) DO s.labels[i] := M3CG.No_label END; IF (cmds = NIL) THEN Init () END; LOOP Skip_white_space (s); op := Scan_id (s); IF (op = M3ID.NoID) THEN EXIT END; IF cmds.get (op, cmd) THEN CmdMap [cmd].proc (s); ELSE Error (s, "** undefined operator: ", M3ID.ToText (op)); END; Skip_line (s); END; END Inhale; PROCEDUREInit () = BEGIN cmds := NEW (IntIntTbl.Default).init (2 * NUMBER (CmdMap)); FOR i := FIRST (CmdMap) TO LAST (CmdMap) DO EVAL cmds.put (M3ID.Add (CmdMap[i].op), i); END; WITH z = Target.TypeNames DO types := NEW (IntIntTbl.Default).init (2 * NUMBER (z)); FOR i := FIRST (z) TO LAST (z) DO EVAL types.put (M3ID.Add (z[i]), ORD (i)); END; END; END Init; PROCEDUREError (<*UNUSED*> VAR s: State; a, b, c: TEXT := NIL) = <*FATAL Wr.Failure, Thread.Alerted*> VAR msg := Target.EOL & "** ERROR in M3CG_Rd.Inhale: "; BEGIN IF (a # NIL) THEN msg := msg & a END; IF (b # NIL) THEN msg := msg & b END; IF (c # NIL) THEN msg := msg & c END; msg := msg & " **" & Target.EOL; Wr.PutText (Stdio.stdout, msg); END Error;
PROCEDURE----------------------------------------------------- compilation units ---Scan_word (VAR s: State): TEXT = VAR buf: ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); BEGIN IF (len = 0) THEN RETURN NIL END; RETURN Text.FromChars (SUBARRAY (buf, 0, len)); END Scan_word; PROCEDUREScan_id (VAR s: State): M3CG.Name = VAR buf: ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); BEGIN IF (len = 0) THEN RETURN M3ID.NoID END; RETURN M3ID.FromStr (SUBARRAY (buf, 0, len)); END Scan_id; PROCEDUREScan_name (VAR s: State): M3CG.Name = VAR buf: ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); BEGIN IF (len = 0) THEN Error (s, "missing name!"); RETURN M3ID.NoID END; IF (len = 1) AND (buf[0] = '*') THEN RETURN M3ID.NoID END; RETURN M3ID.FromStr (SUBARRAY (buf, 0, len)); END Scan_name; PROCEDUREScan_text (VAR s: State): TEXT = CONST Quote = '"'; Escape = '\134'; VAR buf: ARRAY [0..255] OF CHAR; len, d0,d1,d2: INTEGER; overflow := ""; BEGIN Skip_blanks (s); IF (s.ch = '*') THEN GetCh (s); RETURN NIL END; IF (s.ch # Quote) THEN Error (s, "bad text"); RETURN Scan_word (s); END; GetCh (s); (* eat the quote *) len := 0; LOOP IF (s.ch = Quote) THEN GetCh (s); EXIT END; IF (s.ch = EOF) THEN EXIT END; IF (s.ch = Escape) THEN (* escaped character *) IF GetDigit (s, d0) AND GetDigit (s, d1) AND GetDigit (s, d2) THEN s.ch := VAL (d0 * 64 + d1 * 8 + d2, CHAR); END; END; IF (len > LAST (buf)) THEN overflow := overflow & Text.FromChars (SUBARRAY (buf, 0, len)); len := 0; END; buf[len] := s.ch; INC (len); GetCh (s); END; RETURN overflow & Text.FromChars (SUBARRAY (buf, 0, len)); END Scan_text; PROCEDUREGetDigit (VAR s: State; VAR val: INTEGER): BOOLEAN = BEGIN GetCh (s); IF (s.ch < '0') OR ('7' < s.ch) THEN Error (s, "bad octal digit: ", Text.FromChar (s.ch)); val := 0; RETURN FALSE; ELSE val := ORD (s.ch) - ORD ('0'); RETURN TRUE; END; END GetDigit; PROCEDURECvtInt (VAR s: State; READONLY buf: ARRAY OF CHAR): INTEGER = VAR value, used: INTEGER; BEGIN value := Convert.ToInt (buf, used); IF (used # NUMBER (buf)) THEN Error (s, "bad integer: ", Text.FromChars (buf)); END; RETURN value; END CvtInt; PROCEDUREScan_int (VAR s: State): INTEGER = VAR buf : ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); BEGIN RETURN CvtInt (s, SUBARRAY (buf, 0, len)); END Scan_int; PROCEDUREScan_error (VAR s: State): RuntimeError = VAR x := Scan_int (s); BEGIN IF (x < ORD (FIRST (RuntimeError))) OR (ORD (LAST (RuntimeError)) < x) THEN Error (s, "bad error code: ", Fmt.Int (x)); x := ORD (FIRST (RuntimeError)); END; RETURN VAL (x, RuntimeError); END Scan_error; PROCEDUREScan_Tint (VAR s: State): Target.Int = VAR buf: ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); result, tmp: Target.Int; value, used: INTEGER; BEGIN value := Convert.ToInt (SUBARRAY (buf, 0, len), used); IF (used = len) AND TInt.FromInt (value, NUMBER (result.x), result) THEN RETURN result; ELSIF (buf[0] # '-') THEN IF TInt.New (SUBARRAY (buf, 0, len), NUMBER (result.x), result) THEN RETURN result; END; ELSE (* Target doesn't handle negative values *) IF TInt.New (SUBARRAY (buf, 1, len-1), NUMBER (tmp.x), tmp) AND TInt.Subtract (TInt.Zero, tmp, result) THEN RETURN result; END; END; Error (s, "illegal integer: ", Text.FromChars (SUBARRAY (buf, 0, len))); RETURN TInt.Zero; END Scan_Tint; PROCEDUREScan_float (VAR s: State): Target.Float = VAR buf: ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); pre := Target.Precision.Short; result: Target.Float; BEGIN IF (len # 1) THEN BadPrec (s, buf, len); ELSIF (buf[0] = 'R') THEN pre := Target.Precision.Short; ELSIF (buf[0] = 'L') THEN pre := Target.Precision.Long; ELSIF (buf[0] = 'X') THEN pre := Target.Precision.Extended; ELSE BadPrec (s, buf, len); END; len := Scan_buf (s, buf); IF TFloat.New (SUBARRAY(buf,0,len), pre, result) THEN RETURN result END; Error (s, "illegal float: ", Text.FromChars (SUBARRAY (buf, 0, len))); RETURN TFloat.ZeroR; END Scan_float; PROCEDUREBadPrec (VAR s: State; READONLY buf: ARRAY OF CHAR; len: INTEGER) = BEGIN Error (s, "bad floating-point precision: ", Text.FromChars (SUBARRAY (buf, 0, len))); END BadPrec; PROCEDUREScan_type (VAR s: State): M3CG.Type = VAR name := Scan_id (s); val: INTEGER; BEGIN IF types.get (name, val) THEN RETURN VAL (val, M3CG.Type) END; Error (s, "illegal type: ", M3ID.ToText (name)); RETURN M3CG.Type.Int32; END Scan_type; PROCEDUREScan_bool (VAR s: State): BOOLEAN = VAR buf: ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); BEGIN IF (len = 1) THEN IF (buf [0] = 'T') THEN RETURN TRUE; ELSIF (buf[0] = 'F') THEN RETURN FALSE; END; END; Error (s, "illegal boolean: ", Text.FromChars (SUBARRAY (buf, 0, len))); RETURN TRUE; END Scan_bool; PROCEDUREScan_label (VAR s: State): INTEGER = VAR buf: ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); val, x: INTEGER; BEGIN IF (len = 1) AND (buf[0] = '*') THEN RETURN M3CG.No_label; ELSIF (len < 3) OR (buf[0] # 'L') OR (buf[1] # '.') THEN Error (s, "Bad label: ", Text.FromChars(SUBARRAY (buf, 0, len))); RETURN M3CG.No_label; END; val := CvtInt (s, SUBARRAY (buf, 2, len - 2)); IF (val < 0) THEN Error (s, "Bad label: ", Text.FromChars(SUBARRAY (buf, 0, len))); RETURN M3CG.No_label; END; WHILE (val > LAST (s.labels^)) DO ExpandLabels (s) END; x := s.labels[val]; IF (x = M3CG.No_label) THEN x := s.cg.next_label (); s.labels[val] := x; END; RETURN x; END Scan_label; PROCEDUREExpandLabels (VAR s: State) = VAR new := NEW (REF ARRAY OF M3CG.Label, 2 * NUMBER (s.labels^)); BEGIN SUBARRAY (new^, 0, NUMBER (s.labels^)) := s.labels^; FOR i := NUMBER (s.labels^) TO LAST (new^) DO new[i] := M3CG.No_label END; s.labels := new; END ExpandLabels; PROCEDUREScan_tipe (VAR s: State): M3CG.TypeUID = VAR buf: ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); BEGIN RETURN CvtInt (s, SUBARRAY (buf, 0, len)); END Scan_tipe; PROCEDUREScan_varName (VAR s: State): INTEGER = VAR buf: ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); BEGIN IF (len = 1) AND (buf[0] = '*') THEN RETURN -1; ELSIF (len < 3) OR (buf[0] # 'v') OR (buf[1] # '.') THEN Error (s, "Bad variable name: ", Text.FromChars(SUBARRAY (buf, 0, len))); RETURN -1; ELSE RETURN CvtInt (s, SUBARRAY (buf, 2, len - 2)); END; END Scan_varName; PROCEDUREScan_var (VAR s: State): M3CG.Var = VAR id := Scan_varName (s); BEGIN IF (id < 0) THEN RETURN NIL; ELSE RETURN s.vars[id]; END; END Scan_var; PROCEDUREScan_procName (VAR s: State): INTEGER = VAR buf: ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); BEGIN IF (len = 1) AND (buf[0] = '*') THEN RETURN -1; ELSIF (len < 3) OR (buf[0] # 'p') OR (buf[1] # '.') THEN Error (s, "Bad procedure name: ", Text.FromChars (SUBARRAY (buf,0,len))); RETURN -1; ELSE RETURN CvtInt (s, SUBARRAY (buf, 2, len - 2)); END; END Scan_procName; PROCEDUREScan_proc (VAR s: State): M3CG.Proc = VAR id := Scan_procName (s); BEGIN IF (id < 0) THEN RETURN NIL; ELSE RETURN s.procs[id]; END; END Scan_proc; PROCEDUREScan_sign (VAR s: State): M3CG.Sign = VAR buf: ARRAY [0..99] OF CHAR; len := Scan_buf (s, buf); BEGIN IF (len # 1) THEN Error (s, "bad sign: ", Text.FromChars (SUBARRAY (buf, 0, len))); ELSIF (buf[0] = 'X') THEN RETURN M3CG.Sign.Unknown; ELSIF (buf[0] = 'N') THEN RETURN M3CG.Sign.Negative; ELSIF (buf[0] = 'P') THEN RETURN M3CG.Sign.Positive; ELSE Error (s, "bad sign: ", Text.FromChars (SUBARRAY (buf, 0, len))); END; RETURN M3CG.Sign.Unknown; END Scan_sign; PROCEDUREScan_callConv (VAR s: State): Target.CallingConvention = VAR id := Scan_int (s); cc := Target.ConventionFromID (id); BEGIN IF (cc = NIL) THEN Error (s, "unknown calling convention: ", Fmt.Int (id)); END; RETURN cc; END Scan_callConv; PROCEDUREScan_line (VAR s: State): TEXT = VAR buf: ARRAY [0..511] OF CHAR; len: INTEGER; BEGIN len := 0; LOOP IF (s.ch = '\n') OR (s.ch = EOF) THEN EXIT END; IF (len <= LAST (buf)) THEN buf[len] := s.ch; INC (len); END; GetCh (s); END; RETURN Text.FromChars (SUBARRAY (buf, 0, len)); END Scan_line; PROCEDUREScan_buf (VAR s: State; VAR buf: ARRAY OF CHAR): INTEGER = VAR len: INTEGER; BEGIN Skip_blanks (s); len := 0; LOOP IF (s.ch = EOF) THEN EXIT END; IF (s.ch = ' ') OR (s.ch = '\t') OR (s.ch = '\n') THEN EXIT; END; IF (len <= LAST (buf)) THEN buf[len] := s.ch; INC (len); END; GetCh (s); END; RETURN len; END Scan_buf; PROCEDURESkip_blanks (VAR s: State) = BEGIN WHILE (s.ch = ' ') OR (s.ch = '\t') DO GetCh (s) END; END Skip_blanks; PROCEDURESkip_white_space (VAR s: State) = BEGIN WHILE (s.ch = ' ') OR (s.ch = '\n') OR (s.ch = '\t') DO GetCh (s); END; END Skip_white_space; PROCEDURESkip_line (VAR s: State) = BEGIN WHILE (s.ch # '\n') AND (s.ch # EOF) DO GetCh (s) END; GetCh (s); END Skip_line; PROCEDUREGetCh (VAR s: State) = BEGIN REPEAT IF (s.buf_ptr >= s.buf_len) THEN RefillBuffer (s) END; s.ch := s.buf[s.buf_ptr]; INC (s.buf_ptr); UNTIL (s.ch # '\r'); END GetCh; PROCEDURERefillBuffer (VAR s: State) = <*FATAL Rd.Failure, Thread.Alerted*> BEGIN s.buf_ptr := 0; s.buf_len := Rd.GetSub (s.rd, s.buf^); IF (s.buf_len < NUMBER (s.buf^)) THEN (* add an EOF character *) s.buf[s.buf_len] := EOF; INC (s.buf_len); END; END RefillBuffer;
PROCEDURE------------------------------------------------ debugging line numbers ---begin_unit (VAR s: State) = VAR optimize := Scan_int (s); BEGIN s.cg.begin_unit (optimize); END begin_unit; PROCEDUREend_unit (VAR s: State) = BEGIN s.cg.end_unit (); END end_unit; PROCEDUREimport_unit (VAR s: State) = VAR name := Scan_name (s); BEGIN s.cg.import_unit (name); END import_unit; PROCEDUREexport_unit (VAR s: State) = VAR name := Scan_name (s); BEGIN s.cg.export_unit (name); END export_unit;
PROCEDURE------------------------------------------- debugging type declarations ---set_source_file (VAR s: State) = VAR file := Scan_word (s); BEGIN s.cg.set_source_file (file); END set_source_file; PROCEDUREset_source_line (VAR s: State) = VAR line := Scan_int (s); BEGIN s.cg.set_source_line (line); END set_source_line;
PROCEDURE--------------------------------------------------------- runtime hooks ---declare_typename (VAR s: State) = VAR type := Scan_tipe (s); name := Scan_name (s); BEGIN s.cg.declare_typename (type, name); END declare_typename; PROCEDUREdeclare_array (VAR s: State)= VAR type := Scan_tipe (s); index := Scan_tipe (s); elt := Scan_tipe (s); size := Scan_int (s); BEGIN s.cg.declare_array (type, index, elt, size); END declare_array; PROCEDUREdeclare_open_array (VAR s: State)= VAR type := Scan_tipe (s); elt := Scan_tipe (s); size := Scan_int (s); BEGIN s.cg.declare_open_array (type, elt, size); END declare_open_array; PROCEDUREdeclare_enum (VAR s: State) = VAR type := Scan_tipe (s); n_elts := Scan_int (s); size := Scan_int (s); BEGIN s.cg.declare_enum (type, n_elts, size); END declare_enum; PROCEDUREdeclare_enum_elt (VAR s: State) = VAR name := Scan_name (s); BEGIN s.cg.declare_enum_elt (name); END declare_enum_elt; PROCEDUREdeclare_packed (VAR s: State) = VAR type := Scan_tipe (s); size := Scan_int (s); base := Scan_tipe (s); BEGIN s.cg.declare_packed (type, size, base); END declare_packed; PROCEDUREdeclare_record (VAR s: State) = VAR type := Scan_tipe (s); size := Scan_int (s); n_fields := Scan_int (s); BEGIN s.cg.declare_record (type, size, n_fields); END declare_record; PROCEDUREdeclare_field (VAR s: State) = VAR name := Scan_name (s); offset := Scan_int (s); size := Scan_int (s); type := Scan_tipe (s); BEGIN s.cg.declare_field (name, offset, size, type); END declare_field; PROCEDUREdeclare_set (VAR s: State) = VAR type := Scan_tipe (s); domain := Scan_tipe (s); size := Scan_int (s); BEGIN s.cg.declare_set (type, domain, size); END declare_set; PROCEDUREdeclare_subrange (VAR s: State) = VAR type := Scan_tipe (s); domain := Scan_tipe (s); min := Scan_Tint (s); max := Scan_Tint (s); size := Scan_int (s); BEGIN s.cg.declare_subrange (type, domain, min, max, size); END declare_subrange; PROCEDUREdeclare_pointer (VAR s: State) = VAR type := Scan_tipe (s); target := Scan_tipe (s); brand := Scan_text (s); traced := Scan_bool (s); BEGIN s.cg.declare_pointer (type, target, brand, traced); END declare_pointer; PROCEDUREdeclare_indirect (VAR s: State) = VAR type := Scan_tipe (s); target := Scan_tipe (s); BEGIN s.cg.declare_indirect (type, target); END declare_indirect; PROCEDUREdeclare_proctype (VAR s: State) = VAR type := Scan_tipe (s); n_formals := Scan_int (s); result := Scan_tipe (s); n_raises := Scan_int (s); calling := Scan_callConv (s); BEGIN s.cg.declare_proctype (type, n_formals, result, n_raises, calling); END declare_proctype; PROCEDUREdeclare_formal (VAR s: State) = VAR name := Scan_name (s); type := Scan_tipe (s); BEGIN s.cg.declare_formal (name, type); END declare_formal; PROCEDUREdeclare_raises (VAR s: State) = VAR name := Scan_name (s); BEGIN s.cg.declare_raises (name); END declare_raises; PROCEDUREdeclare_object (VAR s: State) = VAR type := Scan_tipe (s); super := Scan_tipe (s); brand := Scan_text (s); traced := Scan_bool (s); n_fields := Scan_int (s); n_methods := Scan_int (s); field_size := Scan_int (s); BEGIN s.cg.declare_object (type, super, brand, traced, n_fields, n_methods, field_size); END declare_object; PROCEDUREdeclare_method (VAR s: State) = VAR name := Scan_name (s); type := Scan_tipe (s); BEGIN s.cg.declare_method (name, type); END declare_method; PROCEDUREdeclare_opaque (VAR s: State) = VAR type := Scan_tipe (s); super := Scan_tipe (s); BEGIN s.cg.declare_opaque (type, super); END declare_opaque; PROCEDUREreveal_opaque (VAR s: State) = VAR lhs := Scan_tipe (s); rhs := Scan_tipe (s); BEGIN s.cg.reveal_opaque (lhs, rhs); END reveal_opaque; PROCEDUREdeclare_exception (VAR s: State) = VAR name := Scan_name (s); arg_type := Scan_tipe (s); raise_proc := Scan_bool (s); base := Scan_var (s); offset := Scan_int (s); BEGIN s.cg.declare_exception (name, arg_type, raise_proc, base, offset); END declare_exception;
PROCEDURE------------------------------------------------- variable declarations ---set_runtime_proc (VAR s: State) = VAR name := Scan_name (s); proc := Scan_proc (s); BEGIN s.cg.set_runtime_proc (name, proc); END set_runtime_proc; PROCEDUREset_runtime_hook (VAR s: State) = VAR name := Scan_name (s); var := Scan_var (s); offset := Scan_int (s); BEGIN s.cg.set_runtime_hook (name, var, offset); END set_runtime_hook; PROCEDUREget_runtime_hook (VAR s: State) = BEGIN Error (s, "unexpected get_runtime_hook"); END get_runtime_hook;
PROCEDURE---------------------------------------- static variable initialization ---AddVar (VAR s: State; id: INTEGER; v: M3CG.Var) = BEGIN WHILE (id >= NUMBER (s.vars^)) DO ExpandVars (s) END; s.vars[id] := v; END AddVar; PROCEDUREExpandVars (VAR s: State) = VAR new := NEW (REF ARRAY OF M3CG.Var, 2 * NUMBER (s.vars^)); BEGIN SUBARRAY (new^, 0, NUMBER (s.vars^)) := s.vars^; s.vars := new; END ExpandVars; PROCEDUREimport_global (VAR s: State) = VAR name := Scan_name (s); size := Scan_int (s); align := Scan_int (s); type := Scan_type (s); m3t := Scan_tipe (s); v := Scan_varName (s); BEGIN AddVar (s, v, s.cg.import_global (name, size, align, type, m3t)); END import_global; PROCEDUREdeclare_segment (VAR s: State) = VAR name := Scan_name (s); m3t := Scan_tipe (s); is_const := Scan_bool (s); v := Scan_varName (s); BEGIN AddVar (s, v, s.cg.declare_segment (name, m3t, is_const)); END declare_segment; PROCEDUREbind_segment (VAR s: State) = VAR v := Scan_var (s); size := Scan_int (s); align := Scan_int (s); type := Scan_type (s); export := Scan_bool (s); init := Scan_bool (s); BEGIN s.cg.bind_segment (v, size, align, type, export, init); END bind_segment; PROCEDUREdeclare_global (VAR s: State) = VAR name := Scan_name (s); size := Scan_int (s); align := Scan_int (s); type := Scan_type (s); m3t := Scan_tipe (s); export := Scan_bool (s); init := Scan_bool (s); v := Scan_varName (s); BEGIN AddVar (s, v, s.cg.declare_global (name, size, align, type, m3t, export, init)); END declare_global; PROCEDUREdeclare_constant (VAR s: State) = VAR name := Scan_name (s); size := Scan_int (s); align := Scan_int (s); type := Scan_type (s); m3t := Scan_tipe (s); export := Scan_bool (s); init := Scan_bool (s); v := Scan_varName (s); BEGIN AddVar (s, v, s.cg.declare_constant (name, size, align, type, m3t, export,init)); END declare_constant; PROCEDUREdeclare_local (VAR s: State) = VAR name := Scan_name (s); size := Scan_int (s); align := Scan_int (s); type := Scan_type (s); m3t := Scan_tipe (s); in_mem := Scan_bool (s); up_lev := Scan_bool (s); freq := Scan_int (s); v := Scan_varName (s); BEGIN AddVar (s, v, s.cg.declare_local (name, size, align, type, m3t, in_mem, up_lev, freq)); END declare_local; PROCEDUREdeclare_param (VAR s: State) = VAR name := Scan_name (s); size := Scan_int (s); align := Scan_int (s); type := Scan_type (s); m3t := Scan_tipe (s); in_mem := Scan_bool (s); up_lev := Scan_bool (s); freq := Scan_int (s); v := Scan_varName (s); BEGIN AddVar (s, v, s.cg.declare_param (name, size, align, type, m3t, in_mem, up_lev, freq)); END declare_param; PROCEDUREdeclare_temp (VAR s: State) = VAR size := Scan_int (s); align := Scan_int (s); type := Scan_type (s); in_mem := Scan_bool (s); v := Scan_varName (s); BEGIN AddVar (s, v, s.cg.declare_temp (size, align, type, in_mem)); END declare_temp; PROCEDUREfree_temp (VAR s: State) = VAR v := Scan_var (s); BEGIN s.cg.free_temp (v); END free_temp;
PROCEDURE------------------------------------------------------------ procedures ---begin_init (VAR s: State) = VAR v := Scan_var (s); BEGIN s.cg.begin_init (v); END begin_init; PROCEDUREend_init (VAR s: State) = VAR v := Scan_var (s); BEGIN s.cg.end_init (v); END end_init; PROCEDUREinit_int (VAR s: State) = VAR offset := Scan_int (s); value := Scan_Tint (s); type := Scan_type (s); BEGIN s.cg.init_int (offset, value, type); END init_int; PROCEDUREinit_proc (VAR s: State) = VAR offset := Scan_int (s); value := Scan_proc (s); BEGIN s.cg.init_proc (offset, value); END init_proc; PROCEDUREinit_label (VAR s: State) = VAR offset := Scan_int (s); value := Scan_label (s); BEGIN s.cg.init_label (offset, value); END init_label; PROCEDUREinit_var (VAR s: State) = VAR offset := Scan_int (s); value := Scan_var (s); bias := Scan_int (s); BEGIN s.cg.init_var (offset, value, bias); END init_var; PROCEDUREinit_offset (VAR s: State) = VAR offset := Scan_int (s); value := Scan_var (s); BEGIN s.cg.init_offset (offset, value); END init_offset; PROCEDUREinit_chars (VAR s: State) = VAR offset := Scan_int (s); value := Scan_text (s); BEGIN s.cg.init_chars (offset, value); END init_chars; PROCEDUREinit_float (VAR s: State) = VAR offset := Scan_int (s); value := Scan_float (s); BEGIN s.cg.init_float (offset, value); END init_float;
PROCEDURE------------------------------------------------------------ statements ---AddProc (VAR s: State; id: INTEGER; p: M3CG.Proc) = BEGIN WHILE (id >= NUMBER (s.procs^)) DO ExpandProcs (s) END; s.procs[id] := p; END AddProc; PROCEDUREExpandProcs (VAR s: State) = VAR new := NEW (REF ARRAY OF M3CG.Proc, 2 * NUMBER (s.procs^)); BEGIN SUBARRAY (new^, 0, NUMBER (s.procs^)) := s.procs^; s.procs := new; END ExpandProcs; PROCEDUREimport_procedure (VAR s: State) = VAR name := Scan_name (s); n_params := Scan_int (s); ret_type := Scan_type (s); calling := Scan_callConv (s); p := Scan_procName (s); BEGIN AddProc (s, p, s.cg.import_procedure (name, n_params, ret_type, calling)); END import_procedure; PROCEDUREdeclare_procedure (VAR s: State) = VAR name := Scan_name (s); n_params := Scan_int (s); ret_type := Scan_type (s); level := Scan_int (s); calling := Scan_callConv (s); export := Scan_bool (s); parent := Scan_proc (s); p := Scan_procName (s); BEGIN AddProc (s, p, s.cg.declare_procedure (name, n_params, ret_type, level, calling, export, parent)); END declare_procedure; PROCEDUREbegin_procedure (VAR s: State) = VAR p := Scan_proc (s); BEGIN s.cg.begin_procedure (p); END begin_procedure; PROCEDUREend_procedure (VAR s: State) = VAR p := Scan_proc (s); BEGIN s.cg.end_procedure (p); END end_procedure; PROCEDUREbegin_block (VAR s: State) = BEGIN s.cg.begin_block (); END begin_block; PROCEDUREend_block (VAR s: State) = BEGIN s.cg.end_block (); END end_block; PROCEDUREnote_procedure_origin (VAR s: State) = VAR p := Scan_proc (s); BEGIN s.cg.note_procedure_origin (p); END note_procedure_origin;
PROCEDURE------------------------------------------------------------ load/store ---set_label (VAR s: State) = VAR label := Scan_label (s); barrier := Scan_bool (s); BEGIN s.cg.set_label (label, barrier); END set_label; PROCEDUREjump (VAR s: State) = VAR label := Scan_label (s); BEGIN s.cg.jump (label); END jump; PROCEDUREif_true (VAR s: State) = VAR type := Scan_type (s); label := Scan_label (s); freq := Scan_int (s); BEGIN s.cg.if_true (type, label, freq); END if_true; PROCEDUREif_false (VAR s: State) = VAR type := Scan_type (s); label := Scan_label (s); freq := Scan_int (s); BEGIN s.cg.if_false (type, label, freq); END if_false; PROCEDUREif_eq (VAR s: State) = BEGIN if_compare (s, CompareOp.EQ); END if_eq; PROCEDUREif_ne (VAR s: State) = BEGIN if_compare (s, CompareOp.NE); END if_ne; PROCEDUREif_gt (VAR s: State) = BEGIN if_compare (s, CompareOp.GT); END if_gt; PROCEDUREif_ge (VAR s: State) = BEGIN if_compare (s, CompareOp.GE); END if_ge; PROCEDUREif_lt (VAR s: State) = BEGIN if_compare (s, CompareOp.LT); END if_lt; PROCEDUREif_le (VAR s: State) = BEGIN if_compare (s, CompareOp.LE); END if_le; PROCEDUREif_compare (VAR s: State; op: CompareOp) = VAR type := Scan_type (s); label := Scan_label (s); freq := Scan_int (s); BEGIN s.cg.if_compare (type, op, label, freq); END if_compare; PROCEDUREcase_jump (VAR s: State) = VAR type := Scan_type (s); n := Scan_int (s); x := NEW (REF ARRAY OF M3CG.Label, n); BEGIN FOR i := 0 TO n-1 DO x[i] := Scan_label (s) END; s.cg.case_jump (type, x^); END case_jump; PROCEDUREexit_proc (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.exit_proc (type); END exit_proc;
PROCEDURE-------------------------------------------------------------- literals ---load (VAR s: State) = VAR v := Scan_var (s); offset := Scan_int (s); src := Scan_type (s); dest := Scan_type (s); BEGIN s.cg.load (v, offset, src, dest); END load; PROCEDUREstore (VAR s: State) = VAR v := Scan_var (s); offset := Scan_int (s); src := Scan_type (s); dest := Scan_type (s); BEGIN s.cg.store (v, offset, src, dest); END store; PROCEDUREload_address (VAR s: State) = VAR v := Scan_var (s); offset := Scan_int (s); BEGIN s.cg.load_address (v, offset); END load_address; PROCEDUREload_indirect (VAR s: State) = VAR offset := Scan_int (s); src := Scan_type (s); dest := Scan_type (s); BEGIN s.cg.load_indirect (offset, src, dest); END load_indirect; PROCEDUREstore_indirect (VAR s: State) = VAR offset := Scan_int (s); src := Scan_type (s); dest := Scan_type (s); BEGIN s.cg.store_indirect (offset, src, dest); END store_indirect;
PROCEDURE------------------------------------------------------------ arithmetic ---load_nil (VAR s: State) = BEGIN s.cg.load_nil (); END load_nil; PROCEDUREload_integer (VAR s: State) = VAR type := Scan_type (s); value := Scan_Tint (s); BEGIN s.cg.load_integer (type, value); END load_integer; PROCEDUREload_float (VAR s: State) = VAR type := Scan_type (s); value := Scan_float (s); BEGIN s.cg.load_float (type, value); END load_float;
PROCEDURE------------------------------------------------------------------ sets ---eq (VAR s: State) = BEGIN compare (s, CompareOp.EQ); END eq; PROCEDUREne (VAR s: State) = BEGIN compare (s, CompareOp.NE); END ne; PROCEDUREgt (VAR s: State) = BEGIN compare (s, CompareOp.GT); END gt; PROCEDUREge (VAR s: State) = BEGIN compare (s, CompareOp.GE); END ge; PROCEDURElt (VAR s: State) = BEGIN compare (s, CompareOp.LT); END lt; PROCEDUREle (VAR s: State) = BEGIN compare (s, CompareOp.LE); END le; PROCEDUREcompare (VAR s: State; op: CompareOp) = VAR src := Scan_type (s); dest := Scan_type (s); BEGIN s.cg.compare (src, dest, op); END compare; PROCEDUREadd (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.add (type); END add; PROCEDUREsubtract (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.subtract (type); END subtract; PROCEDUREmultiply (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.multiply (type); END multiply; PROCEDUREdivide (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.divide (type); END divide; PROCEDUREdiv (VAR s: State) = VAR type := Scan_type (s); a := Scan_sign (s); b := Scan_sign (s); BEGIN s.cg.div (type, a, b); END div; PROCEDUREmod (VAR s: State) = VAR type := Scan_type (s); a := Scan_sign (s); b := Scan_sign (s); BEGIN s.cg.mod (type, a, b); END mod; PROCEDUREnegate (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.negate (type); END negate; PROCEDUREabs (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.abs (type); END abs; PROCEDUREmax (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.max (type); END max; PROCEDUREmin (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.min (type); END min; PROCEDUREround (VAR s: State) = BEGIN cvt_int (s, ConvertOp.Round); END round; PROCEDUREtrunc (VAR s: State) = BEGIN cvt_int (s, ConvertOp.Trunc); END trunc; PROCEDUREfloor (VAR s: State) = BEGIN cvt_int (s, ConvertOp.Floor); END floor; PROCEDUREceiling (VAR s: State) = BEGIN cvt_int (s, ConvertOp.Ceiling); END ceiling; PROCEDUREcvt_int (VAR s: State; op: ConvertOp) = VAR src := Scan_type (s); dest := Scan_type (s); BEGIN s.cg.cvt_int (src, dest, op); END cvt_int; PROCEDUREcvt_float (VAR s: State) = VAR src := Scan_type (s); dest := Scan_type (s); BEGIN s.cg.cvt_float (src, dest); END cvt_float;
PROCEDURE------------------------------------------------- Word.T bit operations ---set_union (VAR s: State) = VAR size := Scan_int (s); BEGIN s.cg.set_union (size); END set_union; PROCEDUREset_difference (VAR s: State) = VAR size := Scan_int (s); BEGIN s.cg.set_difference (size); END set_difference; PROCEDUREset_intersection (VAR s: State) = VAR size := Scan_int (s); BEGIN s.cg.set_intersection (size); END set_intersection; PROCEDUREset_sym_difference (VAR s: State) = VAR size := Scan_int (s); BEGIN s.cg.set_sym_difference (size); END set_sym_difference; PROCEDUREset_member (VAR s: State) = VAR size := Scan_int (s); type := Scan_type (s); BEGIN s.cg.set_member (size, type); END set_member; PROCEDUREset_eq (VAR s: State) = BEGIN set_compare (s, CompareOp.EQ); END set_eq; PROCEDUREset_ne (VAR s: State) = BEGIN set_compare (s, CompareOp.NE); END set_ne; PROCEDUREset_gt (VAR s: State) = BEGIN set_compare (s, CompareOp.GT); END set_gt; PROCEDUREset_ge (VAR s: State) = BEGIN set_compare (s, CompareOp.GE); END set_ge; PROCEDUREset_lt (VAR s: State) = BEGIN set_compare (s, CompareOp.LT); END set_lt; PROCEDUREset_le (VAR s: State) = BEGIN set_compare (s, CompareOp.LE); END set_le; PROCEDUREset_compare (VAR s: State; op: CompareOp) = VAR size := Scan_int (s); type := Scan_type (s); BEGIN s.cg.set_compare (size, op, type); END set_compare; PROCEDUREset_range (VAR s: State) = VAR size := Scan_int (s); type := Scan_type (s); BEGIN s.cg.set_range (size, type); END set_range; PROCEDUREset_singleton (VAR s: State) = VAR size := Scan_int (s); type := Scan_type (s); BEGIN s.cg.set_singleton (size, type); END set_singleton;
PROCEDURE------------------------------------------------ misc. stack/memory ops ---not (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.not (type); END not; PROCEDUREand (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.and (type); END and; PROCEDUREor (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.or (type); END or; PROCEDURExor (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.xor (type); END xor; PROCEDUREshift (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.shift (type); END shift; PROCEDUREshift_left (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.shift_left (type); END shift_left; PROCEDUREshift_right (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.shift_right (type); END shift_right; PROCEDURErotate (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.rotate (type); END rotate; PROCEDURErotate_left (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.rotate_left (type); END rotate_left; PROCEDURErotate_right (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.rotate_right (type); END rotate_right; PROCEDUREwiden (VAR s: State) = VAR sign_extend := Scan_bool (s); BEGIN s.cg.widen (sign_extend); END widen; PROCEDUREchop (VAR s: State) = BEGIN s.cg.chop (); END chop; PROCEDUREextract (VAR s: State) = VAR type := Scan_type (s); sign_extend := Scan_bool (s); BEGIN s.cg.extract (type, sign_extend); END extract; PROCEDUREextract_n (VAR s: State) = VAR type := Scan_type (s); sign_extend := Scan_bool (s); width := Scan_int (s); BEGIN s.cg.extract_n (type, sign_extend, width); END extract_n; PROCEDUREextract_mn (VAR s: State) = VAR type := Scan_type (s); sign_extend := Scan_bool (s); offset := Scan_int (s); width := Scan_int (s); BEGIN s.cg.extract_mn (type, sign_extend, offset, width); END extract_mn; PROCEDUREinsert (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.insert (type); END insert; PROCEDUREinsert_n (VAR s: State) = VAR type := Scan_type (s); width := Scan_int (s); BEGIN s.cg.insert_n (type, width); END insert_n; PROCEDUREinsert_mn (VAR s: State) = VAR type := Scan_type (s); offset := Scan_int (s); width := Scan_int (s); BEGIN s.cg.insert_mn (type, offset, width); END insert_mn;
PROCEDURE----------------------------------------------------------- conversions ---swap (VAR s: State) = VAR a := Scan_type (s); b := Scan_type (s); BEGIN s.cg.swap (a, b); END swap; PROCEDUREpop (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.pop (type); END pop; PROCEDUREcopy_n (VAR s: State) = VAR cnt_type := Scan_type (s); type := Scan_type (s); overlap := Scan_bool (s); BEGIN s.cg.copy_n (cnt_type, type, overlap); END copy_n; PROCEDUREcopy (VAR s: State) = VAR cnt := Scan_int (s); type := Scan_type (s); overlap := Scan_bool (s); BEGIN s.cg.copy (cnt, type, overlap); END copy; PROCEDUREzero_n (VAR s: State) = VAR cnt_type := Scan_type (s); type := Scan_type (s); BEGIN s.cg.zero_n (cnt_type, type); END zero_n; PROCEDUREzero (VAR s: State) = VAR cnt := Scan_int (s); type := Scan_type (s); BEGIN s.cg.zero (cnt, type); END zero;
PROCEDURE------------------------------------------------ traps & runtime checks ---loophole (VAR s: State) = VAR from := Scan_type (s); two := Scan_type (s); BEGIN s.cg.loophole (from, two); END loophole;
PROCEDURE---------------------------------------------------- address arithmetic ---abort (VAR s: State) = VAR code := Scan_error (s); BEGIN s.cg.abort (code); END abort; PROCEDUREcheck_nil (VAR s: State) = VAR code := Scan_error (s); BEGIN s.cg.check_nil (code); END check_nil; PROCEDUREcheck_lo (VAR s: State) = VAR type := Scan_type (s); i := Scan_Tint (s); code := Scan_error (s); BEGIN s.cg.check_lo (type, i, code); END check_lo; PROCEDUREcheck_hi (VAR s: State) = VAR type := Scan_type (s); i := Scan_Tint (s); code := Scan_error (s); BEGIN s.cg.check_hi (type, i, code); END check_hi; PROCEDUREcheck_range (VAR s: State) = VAR type := Scan_type (s); a := Scan_Tint (s); b := Scan_Tint (s); code := Scan_error (s); BEGIN s.cg.check_range (type, a, b, code); END check_range; PROCEDUREcheck_index (VAR s: State) = VAR type := Scan_type (s); code := Scan_error (s); BEGIN s.cg.check_index (type, code); END check_index; PROCEDUREcheck_eq (VAR s: State) = VAR type := Scan_type (s); code := Scan_error (s); BEGIN s.cg.check_eq (type, code); END check_eq;
PROCEDURE------------------------------------------------------- procedure calls ---add_offset (VAR s: State) = VAR i := Scan_int (s); BEGIN s.cg.add_offset (i); END add_offset; PROCEDUREindex_address (VAR s: State) = VAR type := Scan_type (s); size := Scan_int (s); BEGIN s.cg.index_address (type, size); END index_address;
PROCEDURE------------------------------------------- procedure and closure types ---start_call_direct (VAR s: State) = VAR p := Scan_proc (s); level := Scan_int (s); type := Scan_type (s); BEGIN s.cg.start_call_direct (p, level, type); END start_call_direct; PROCEDUREstart_call_indirect (VAR s: State) = VAR type := Scan_type (s); calling := Scan_callConv (s); BEGIN s.cg.start_call_indirect (type, calling); END start_call_indirect; PROCEDUREpop_param (VAR s: State) = VAR type := Scan_type (s); BEGIN s.cg.pop_param (type); END pop_param; PROCEDUREpop_struct (VAR s: State) = VAR size := Scan_int (s); align := Scan_int (s); BEGIN s.cg.pop_struct (size, align); END pop_struct; PROCEDUREpop_static_link (VAR s: State) = BEGIN s.cg.pop_static_link (); END pop_static_link; PROCEDUREcall_direct (VAR s: State) = VAR p := Scan_proc (s); type := Scan_type (s); BEGIN s.cg.call_direct (p, type); END call_direct; PROCEDUREcall_indirect (VAR s: State) = VAR type := Scan_type (s); calling := Scan_callConv (s); BEGIN s.cg.call_indirect (type, calling); END call_indirect;
PROCEDURE----------------------------------------------------------------- misc. ---load_procedure (VAR s: State) = VAR p := Scan_proc (s); BEGIN s.cg.load_procedure (p); END load_procedure; PROCEDUREload_static_link (VAR s: State) = VAR p := Scan_proc (s); BEGIN s.cg.load_static_link (p); END load_static_link;
PROCEDURE--------------------------------------------------------------- atomics ---comment (VAR s: State) = VAR x: TEXT; BEGIN GetCh (s); (* eat the blank that the writer inserts *) x := Scan_line (s); s.cg.comment (x); END comment;
PROCEDUREstore_ordered (VAR s: State) = VAR src := Scan_type (s); dest := Scan_type (s); order := Scan_int (s); BEGIN s.cg.store_ordered (src, dest, VAL(order, MemoryOrder)); END store_ordered; PROCEDUREload_ordered (VAR s: State) = VAR src := Scan_type (s); dest := Scan_type (s); order := Scan_int (s); BEGIN s.cg.load_ordered (src, dest, VAL(order, MemoryOrder)); END load_ordered; PROCEDUREexchange (VAR s: State) = VAR src := Scan_type (s); dest := Scan_type (s); order := Scan_int (s); BEGIN s.cg.exchange (src, dest, VAL(order, MemoryOrder)); END exchange; PROCEDUREcompare_exchange (VAR s: State) = VAR src := Scan_type (s); dest := Scan_type (s); result := Scan_type (s); success:= Scan_int (s); failure:= Scan_int (s); BEGIN s.cg.compare_exchange (src, dest, result, VAL(success, MemoryOrder), VAL(failure, MemoryOrder)); END compare_exchange; PROCEDUREfence (VAR s: State) = VAR order := Scan_int (s); BEGIN s.cg.fence (VAL(order, MemoryOrder)); END fence; PROCEDUREfetch_and_op (VAR s: State; op: AtomicOp) = VAR src := Scan_type (s); dest := Scan_type (s); order := Scan_int (s); BEGIN s.cg.fetch_and_op (op, src, dest, VAL(order, MemoryOrder)); END fetch_and_op; PROCEDUREfetch_and_add (VAR s: State) = BEGIN fetch_and_op (s, AtomicOp.Add); END fetch_and_add; PROCEDUREfetch_and_sub (VAR s: State) = BEGIN fetch_and_op (s, AtomicOp.Sub); END fetch_and_sub; PROCEDUREfetch_and_or (VAR s: State) = BEGIN fetch_and_op (s, AtomicOp.Or); END fetch_and_or; PROCEDUREfetch_and_and (VAR s: State) = BEGIN fetch_and_op (s, AtomicOp.And); END fetch_and_and; PROCEDUREfetch_and_xor (VAR s: State) = BEGIN fetch_and_op (s, AtomicOp.Xor); END fetch_and_xor; BEGIN END M3CG_Rd.