#ifndef NORCSID static char rcsid[] = "$Header$"; #endif #include "assert.h" #include "param.h" #include "tables.h" #include "types.h" #include #include "data.h" #include "result.h" #include "extern.h" /* * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". * * Author: Hans van Staveren */ unsigned costcalc(); move(tp1,tp2,ply,toplevel,maxcost) token_p tp1,tp2; unsigned maxcost; { register move_p mp; register unsigned t; register struct reginfo *rp; tkdef_p tdp; int i; unsigned codegen(); if (eqtoken(tp1,tp2)) return(0); if (tp2->t_token == -1) { if (tp1->t_token == -1) { if (eqtoken(&machregs[tp1->t_att[0].ar].r_contents, &machregs[tp2->t_att[0].ar].r_contents) && machregs[tp1->t_att[0].ar].r_contents.t_token!=0) return(0); erasereg(tp2->t_att[0].ar); machregs[tp2->t_att[0].ar].r_contents = machregs[tp1->t_att[0].ar].r_contents ; } else { if (eqtoken(&machregs[tp2->t_att[0].ar].r_contents,tp1)) return(0); erasereg(tp2->t_att[0].ar); machregs[tp2->t_att[0].ar].r_contents = *tp1; } for (rp=machregs+1;rpr_contents.t_token == 0) continue; assert(rp->r_contents.t_token > 0); tdp = &tokens[rp->r_contents.t_token]; for (i=0;it_type[i] == EV_REG && clash(rp->r_contents.t_att[i].ar,tp2->t_att[0].ar)) { erasereg(rp-machregs); break; } } } else if (tp1->t_token == -1) { if (eqtoken(tp2,&machregs[tp1->t_att[0].ar].r_contents)) return(0); machregs[tp1->t_att[0].ar].r_contents = *tp2; } /* * If we arrive here the move must really be executed */ for (mp=moves;mp->m_set1>=0;mp++) { if (!match(tp1,&machsets[mp->m_set1],mp->m_expr1)) continue; if (match(tp2,&machsets[mp->m_set2],mp->m_expr2)) break; /* * Correct move rule is found */ } assert(mp->m_set1>=0); /* * To get correct interpretation of things like %[1] * in move code we stack tp2 and tp1. This little trick * saves a lot of testing in other places. */ fakestack[stackheight] = *tp2; fakestack[stackheight+1] = *tp1; stackheight += 2; tokpatlen += 2; t = codegen(&coderules[mp->m_cindex],ply,toplevel,maxcost,0); tokpatlen -= 2; stackheight -= 2; return(t); } #define cocoreg machregs[0].r_contents setcc(tp) token_p tp; { cocoreg = *tp; } test(tp,ply,toplevel,maxcost) token_p tp; unsigned maxcost; { register test_p mp; register unsigned t; register struct reginfo *rp; tkdef_p tdp; int i; unsigned codegen(); if (cocoreg.t_token!=0) { if (eqtoken(tp,&cocoreg)) return(0); if (tp->t_token == -1) { if (eqtoken(&machregs[tp->t_att[0].ar].r_contents,&cocoreg)) return(0); } } /* * If we arrive here the test must really be executed */ for (mp=tests;mp->t_set>=0;mp++) { if (match(tp,&machsets[mp->t_set],mp->t_expr)) break; /* * Correct move rule is found */ } assert(mp->t_set>=0); /* * To get correct interpretation of things like %[1] * in test code we stack tp. This little trick * saves a lot of testing in other places. */ fakestack[stackheight] = *tp; stackheight++; tokpatlen++; t = codegen(&coderules[mp->t_cindex],ply,toplevel,maxcost,0); tokpatlen--; stackheight--; return(t); }