1 /***************************** alpha/gen.c *************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 behandeln des Java-Stacks
9 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
11 Last Change: 1996/11/14
13 *******************************************************************************/
16 static stackinfo *tos; /* Top of Stack */
20 /********************* Verwaltungsfunktionen *********************************/
22 static void stack_init() { tos = NULL; }
24 static stackinfo *stack_get () { return tos; }
26 static void stack_restore (stackinfo *s) { tos = s; }
28 static bool stack_isempty () { return tos == NULL; }
32 /********************** Funktion: stack_topslots ******************************
34 liefert die Anzahl der JavaVM-slots, die die oberste Pseudovariable am
35 Stack belegt (entweder 2 bei LONG und DOUBLE, oder 1 sonst)
37 ******************************************************************************/
39 static u2 stack_topslots ()
42 if (!tos) panic ("Stack is empty on attempt to determine top slots");
44 t = var_type (tos->var);
45 return ( (t==TYPE_LONG) || (t==TYPE_DOUBLE) ) ? 2 : 1;
49 /********************* Funktion: stack_push ***********************************
51 erzeugt eine neues Pseudoregister eines gew"unschten Typs und gibt
52 es oben auf den Stack.
53 Ausserdem liefert die Funktion den Zeiger auf dieses Pseudoregister
55 ******************************************************************************/
57 static varinfo *stack_push (u2 type)
59 stackinfo *s = DNEW (stackinfo);
62 s -> var = var_create (type);
69 /********************** Funktion: stack_repush ********************************
71 Gibt ein bereits vorhandenen Pseudoregister auf den Stack
73 ******************************************************************************/
75 static void stack_repush (varinfo *v)
77 stackinfo *s = DNEW (stackinfo);
86 /********************** Funktion: stack_pop ***********************************
88 nimmt das oberste Pseudoregister vom Stack, dabei wird aber
89 "uberpr"uft, ob der Typ stimmt.
91 ******************************************************************************/
93 static varinfo *stack_pop (u2 type)
97 if (!tos) panic ("Stack is empty on attempt to pop");
102 if (var_type (v) != type) panic ("Popped invalid element from stack");
107 /********************* Funktion: stack_popany ********************************
109 nimmt das oberste Pseudoregister vom stack, ohne Typ"uberpr"ufung
110 durchzuf"uhren, wobei aber zumindest die Anzahl der notwendigen
111 Slots "ubereinstimmen muss.
113 ******************************************************************************/
115 static varinfo *stack_popany (u2 slots)
119 if (!tos) panic ("Stack is empty on attempt to pop");
120 if (slots != stack_topslots() )
121 panic ("Pop would tear LONG/DOUBLE-Datatype apart");
131 /********************** Funktion: stack_popmany *******************************
133 nimmt vom Stack soviele Pseudoregister, dass die Anzahl der von
134 ihnen belegten Slots die gew"unschte Menge ergeben.
135 Zeiger auf dieses Pseudoregister werden im Array vars gespeichert, und
136 deren tats"achliche Anzahl als Funktionswert zur"uckgeliefert.
137 (Haupts"achlich f"ur die Typneutralen DUP/POP.. Operationen)
139 ******************************************************************************/
141 static u2 stack_popmany (varid *vars, u2 slots)
148 if (ts > slots) panic ("POP would tear LONG/DOUBLE-Datatype apart");
149 vars[(varcount)++] = stack_popany(ts);
156 /********************** Funktion: stack_pushmany ******************************
158 Gibt eine Anzahl von Pseudoregister auf den Stack.
160 ******************************************************************************/
162 static void stack_repushmany (u2 varcount, varid *vars)
165 for (i=0; i<varcount; i++) stack_repush(vars[(varcount-1)-i]);
169 /***************** Funktion: stack_addjoincode ********************************
171 erzeugt die passenden MOVE-Commandos, sodass alle Pseudoregisterinhalte
172 eines Stacks auf die Pseudoregister eines anderen Stacks kopiert
174 Dann wird der Zielstack als neuer aktueller Stack verwendet.
175 (F"ur allem f"ur Verzweigungs- und Sprungbefehle)
177 *******************************************************************************/
179 static void stack_jointail (stackinfo *now, stackinfo *then)
184 if (now==then) return;
185 if ( (now==NULL) || (then==NULL) )
186 panic ("Stacks of different length on join");
192 if (t != var_type (v2))
193 panic ("Mismatching stack types on join of control flow");
195 pcmd_move_n_drop (t, v1,v2);
198 stack_jointail (now -> prev, then -> prev);
202 static void stack_addjoincode (stackinfo *targetstack)
204 stack_jointail (tos, targetstack);
209 /******************* Funktion: stack_makesaved ********************************
211 Kennzeichnet alle am Stack befindlichen Pseudoregister als
212 zu sichernde Register.
214 *******************************************************************************/
216 static void stack_makesaved ()
220 var_makesaved (s->var);
226 /******************* Funktion: stack_display **********************************
228 Gibt den Inhalt des Stacks aus (also die Pseudoregister, die am
230 (Nur zu Debug-Zwecken)
232 ******************************************************************************/
234 static void stack_display (stackinfo *s)
237 stack_display (s->prev);
238 var_display (s->var);