summaryrefslogtreecommitdiff
path: root/src/cmd/5c/sgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/5c/sgen.c')
-rw-r--r--src/cmd/5c/sgen.c422
1 files changed, 5 insertions, 417 deletions
diff --git a/src/cmd/5c/sgen.c b/src/cmd/5c/sgen.c
index e18cb6168..1584ecff3 100644
--- a/src/cmd/5c/sgen.c
+++ b/src/cmd/5c/sgen.c
@@ -28,410 +28,16 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-#include "gc.h"
-
-int32
-argsize(void)
-{
- Type *t;
- int32 s;
-//print("t=%T\n", thisfn);
- s = 0;
- for(t=thisfn->down; t!=T; t=t->down) {
- switch(t->etype) {
- case TVOID:
- break;
- case TDOT:
- s += 64;
- break;
- default:
- s = align(s, t, Aarg1);
- s = align(s, t, Aarg2);
- break;
- }
-//print(" %d %T\n", s, t);
- }
- return (s+7) & ~7;
-}
+#include "gc.h"
-void
-codgen(Node *n, Node *nn)
+Prog*
+gtext(Sym *s, int32 stkoff)
{
- Prog *sp;
- Node *n1, nod, nod1;
-
- cursafe = 0;
- curarg = 0;
- maxargsafe = 0;
-
- /*
- * isolate name
- */
- for(n1 = nn;; n1 = n1->left) {
- if(n1 == Z) {
- diag(nn, "cant find function name");
- return;
- }
- if(n1->op == ONAME)
- break;
- }
- nearln = nn->lineno;
- gpseudo(ATEXT, n1->sym, nodconst(stkoff));
+ gpseudo(ATEXT, s, nodconst(stkoff));
p->to.type = D_CONST2;
p->to.offset2 = argsize();
-
- sp = p;
-
- /*
- * isolate first argument
- */
- if(REGARG >= 0) {
- if(typesuv[thisfn->link->etype]) {
- nod1 = *nodret->left;
- nodreg(&nod, &nod1, REGARG);
- gopcode(OAS, &nod, Z, &nod1);
- } else
- if(firstarg && typechlp[firstargtype->etype]) {
- nod1 = *nodret->left;
- nod1.sym = firstarg;
- nod1.type = firstargtype;
- nod1.xoffset = align(0, firstargtype, Aarg1);
- nod1.etype = firstargtype->etype;
- nodreg(&nod, &nod1, REGARG);
- gopcode(OAS, &nod, Z, &nod1);
- }
- }
-
- retok = 0;
- gen(n);
- if(!retok)
- if(thisfn->link->etype != TVOID)
- warn(Z, "no return at end of function: %s", n1->sym->name);
- noretval(3);
- gbranch(ORETURN);
-
- if(!debug['N'] || debug['R'] || debug['P'])
- regopt(sp);
-
- sp->to.offset += maxargsafe;
-}
-
-void
-supgen(Node *n)
-{
- int32 spc;
- Prog *sp;
-
- if(n == Z)
- return;
- suppress++;
- spc = pc;
- sp = lastp;
- gen(n);
- lastp = sp;
- pc = spc;
- sp->link = nil;
- suppress--;
-}
-
-void
-gen(Node *n)
-{
- Node *l, nod;
- Prog *sp, *spc, *spb;
- Case *cn;
- int32 sbc, scc;
- int o, f;
-
-loop:
- if(n == Z)
- return;
- nearln = n->lineno;
- o = n->op;
- if(debug['G'])
- if(o != OLIST)
- print("%L %O\n", nearln, o);
-
- retok = 0;
- switch(o) {
-
- default:
- complex(n);
- cgen(n, Z, 0);
- break;
-
- case OLIST:
- gen(n->left);
-
- rloop:
- n = n->right;
- goto loop;
-
- case ORETURN:
- retok = 1;
- complex(n);
- if(n->type == T)
- break;
- l = n->left;
- if(l == Z) {
- noretval(3);
- gbranch(ORETURN);
- break;
- }
- if(typesuv[n->type->etype]) {
- sugen(l, nodret, n->type->width);
- noretval(3);
- gbranch(ORETURN);
- break;
- }
- regret(&nod, n);
- cgen(l, &nod, 0);
- regfree(&nod);
- if(typefd[n->type->etype])
- noretval(1);
- else
- noretval(2);
- gbranch(ORETURN);
- break;
-
- case OLABEL:
- l = n->left;
- if(l) {
- l->pc = pc;
- if(l->label)
- patch(l->label, pc);
- }
- gbranch(OGOTO); /* prevent self reference in reg */
- patch(p, pc);
- goto rloop;
-
- case OGOTO:
- retok = 1;
- n = n->left;
- if(n == Z)
- return;
- if(n->complex == 0) {
- diag(Z, "label undefined: %s", n->sym->name);
- return;
- }
- if(suppress)
- return;
- gbranch(OGOTO);
- if(n->pc) {
- patch(p, n->pc);
- return;
- }
- if(n->label)
- patch(n->label, pc-1);
- n->label = p;
- return;
-
- case OCASE:
- l = n->left;
- if(cases == C)
- diag(n, "case/default outside a switch");
- if(l == Z) {
- cas();
- cases->val = 0;
- cases->def = 1;
- cases->label = pc;
- goto rloop;
- }
- complex(l);
- if(l->type == T)
- goto rloop;
- if(l->op == OCONST)
- if(typechl[l->type->etype]) {
- cas();
- cases->val = l->vconst;
- cases->def = 0;
- cases->label = pc;
- goto rloop;
- }
- diag(n, "case expression must be integer constant");
- goto rloop;
-
- case OSWITCH:
- l = n->left;
- complex(l);
- if(l->type == T)
- break;
- if(!typechl[l->type->etype]) {
- diag(n, "switch expression must be integer");
- break;
- }
-
- gbranch(OGOTO); /* entry */
- sp = p;
-
- cn = cases;
- cases = C;
- cas();
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- gen(n->right);
- gbranch(OGOTO);
- patch(p, breakpc);
-
- patch(sp, pc);
- regalloc(&nod, l, Z);
- nod.type = types[TLONG];
- cgen(l, &nod, 0);
- doswit(&nod);
- regfree(&nod);
- patch(spb, pc);
-
- cases = cn;
- breakpc = sbc;
- break;
-
- case OWHILE:
- case ODWHILE:
- l = n->left;
- gbranch(OGOTO); /* entry */
- sp = p;
-
- scc = continpc;
- continpc = pc;
- gbranch(OGOTO);
- spc = p;
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- patch(spc, pc);
- if(n->op == OWHILE)
- patch(sp, pc);
- bcomplex(l, Z); /* test */
- patch(p, breakpc);
-
- if(n->op == ODWHILE)
- patch(sp, pc);
- gen(n->right); /* body */
- gbranch(OGOTO);
- patch(p, continpc);
-
- patch(spb, pc);
- continpc = scc;
- breakpc = sbc;
- break;
-
- case OFOR:
- l = n->left;
- gen(l->right->left); /* init */
- gbranch(OGOTO); /* entry */
- sp = p;
-
- scc = continpc;
- continpc = pc;
- gbranch(OGOTO);
- spc = p;
-
- sbc = breakpc;
- breakpc = pc;
- gbranch(OGOTO);
- spb = p;
-
- patch(spc, pc);
- gen(l->right->right); /* inc */
- patch(sp, pc);
- if(l->left != Z) { /* test */
- bcomplex(l->left, Z);
- patch(p, breakpc);
- }
- gen(n->right); /* body */
- gbranch(OGOTO);
- patch(p, continpc);
-
- patch(spb, pc);
- continpc = scc;
- breakpc = sbc;
- break;
-
- case OCONTINUE:
- if(continpc < 0) {
- diag(n, "continue not in a loop");
- break;
- }
- gbranch(OGOTO);
- patch(p, continpc);
- break;
-
- case OBREAK:
- if(breakpc < 0) {
- diag(n, "break not in a loop");
- break;
- }
- gbranch(OGOTO);
- patch(p, breakpc);
- break;
-
- case OIF:
- l = n->left;
- if(bcomplex(l, n->right)) {
- if(typefd[l->type->etype])
- f = !l->fconst;
- else
- f = !l->vconst;
- if(debug['c'])
- print("%L const if %s\n", nearln, f ? "false" : "true");
- if(f) {
- supgen(n->right->left);
- gen(n->right->right);
- }
- else {
- gen(n->right->left);
- supgen(n->right->right);
- }
- }
- else {
- sp = p;
- if(n->right->left != Z)
- gen(n->right->left);
- if(n->right->right != Z) {
- gbranch(OGOTO);
- patch(sp, pc);
- sp = p;
- gen(n->right->right);
- }
- patch(sp, pc);
- }
- break;
-
- case OSET:
- case OUSED:
- usedset(n->left, o);
- break;
- }
-}
-
-void
-usedset(Node *n, int o)
-{
- if(n->op == OLIST) {
- usedset(n->left, o);
- usedset(n->right, o);
- return;
- }
- complex(n);
- switch(n->op) {
- case OADDR: /* volatile */
- gins(ANOP, n, Z);
- break;
- case ONAME:
- if(o == OSET)
- gins(ANOP, Z, n);
- else
- gins(ANOP, n, Z);
- break;
- }
+ return p;
}
void
@@ -651,21 +257,3 @@ xcom(Node *n)
break;
}
}
-
-int
-bcomplex(Node *n, Node *c)
-{
-
- complex(n);
- if(n->type != T)
- if(tcompat(n, T, n->type, tnot))
- n->type = T;
- if(n->type != T) {
- if(c != Z && n->op == OCONST && deadheads(c))
- return 1;
- bool64(n);
- boolgen(n, 1, Z);
- } else
- gbranch(OGOTO);
- return 0;
-}