+void make_call(struct treenode *bnode, short skippop)
+{
+ short *sc = bnode->sc;
+ int j, off = 0;
+ printf("\t//params pushen (skippop: %d)\n", skippop);
+ for(j = 0; j < bnode->soffset; j++) {
+ if(sc[j] == 1)
+ printf("\txchg %%%s, %d(%%rsp)\n", param_reg(j), (j - off)*8);
+ else {
+ if (sc[j] == 0) {
+ printf("\tpushq %%%s\n", param_reg(j));
+ off++;
+ }
+ }
+ }
+ printf("\t//vars pushen\n");
+ for(j = bnode->soffset; j < bnode->soffset + bnode->vars; j++) {
+ printf("\tpushq %%%s\n", param_reg(j));
+ }
+
+ /* TODO: schoener machen... */
+ if(strcmp(BN_REG, "rax")!=0) {
+ printf("\t//tmp register pushen\n");
+ printf("\tpushq %%rax\n");
+ if(strcmp(BN_REG, "r10")!=0) {
+ printf("\tpushq %%r10\n");
+ }
+ }
+ printf("\tcall %s\n", bnode->name);
+ if(strcmp(BN_REG, "rax")!=0) {
+ move("rax", BN_REG);
+ if(skippop)
+ goto cleanup;
+ if(strcmp(BN_REG, "r10")!=0) {
+ printf("\tpopq %%r10\n");
+ }
+ printf("\tpopq %%rax\n");
+ }
+ if(skippop)
+ goto cleanup;
+
+ printf("\t//vars poppen\n");
+ for(j = bnode->soffset + bnode->vars - 1; j > bnode->soffset - 1; j--) {
+ printf("\tpopq %%%s\n", param_reg(j));
+ }
+
+ printf("\t//params poppen (sc == 0)\n");
+ for(j = bnode->soffset - 1; j >= 0; j--) {
+ if(sc[j] == 0)
+ printf("\tpopq %%%s\n", param_reg(j));
+ }
+ printf("\t//params poppen (sc != 0)\n");
+ for(j = 0; j < bnode->soffset; j++) {
+ if(sc[j] > 0)
+ printf("\tpopq %%%s\n", param_reg(j));
+ }
+
+cleanup:
+ /* clear stack_control array */
+ for(j = 0; j < sizeof sc / sizeof sc[0]; j++)
+ sc[j] = 0;
+}
+
+void prep_arg(struct treenode *bnode, int moveit)
+{
+ short *sc = bnode->sc;
+ printf("\t//args-nr-> %i (%%%s) [moveit= %i]\n", bnode->soffset, param_reg(bnode->soffset), moveit);
+ sc[bnode->soffset] = 1;
+ if(moveit == 1) { /* expr */
+ if(( bnode->kids[0] != TREENULL && bnode->kids[0]->op == O_NOTHING &&
+ bnode->kids[0] != TREENULL && bnode->kids[0]->op == O_NOTHING)) {
+ printf("\tpushq %%%s\n", param_reg(bnode->soffset));
+ sc[bnode->soffset] = 2;
+ } else {
+ printf("\tpushq %%%s\n", BN_REG);
+ }
+ } else if(moveit == 2) { /* O_ID right */
+ KIDREG2PARM(1);
+ printf("\tpushq %%%s\n", KID_REG(1));
+ } else if(moveit == 0) { /* O_ID left */
+ KIDREG2PARM(0);
+ printf("\tpushq %%%s\n", KID_REG(0));
+ }
+}
+
+void gen_sub_field(struct treenode *bnode)
+{
+ /* siehe intelli_03.0 @ gesamt */
+ printf("\t//gen_sub_field\n");
+ KIDKIDREG2PARM(1,0);
+ if(!(strcmp(bnode->kids[0]->kids[0]->kids[0]->name, bnode->kids[1]->kids[0]->name) == 0 &&
+ bnode->kids[0]->kids[0]->soffset == bnode->kids[1]->soffset)) {
+ KIDKIDKIDREG2PARM(0,0,0);
+ printf("\tmov %d(%%%s), %%%s\n", bnode->kids[0]->kids[0]->soffset * 8, KIDKIDKID_REG(0,0,0), BN_REG);
+ printf("\tmov %%%s, %d(%%%s)\n", BN_REG, bnode->kids[1]->soffset * 8, KIDKID_REG(1,0));
+ }
+ printf("\tsub $%d, %d(%%%s)\n", bnode->kids[0]->kids[1]->val, bnode->kids[1]->soffset * 8, KIDKID_REG(1,0));
+}
+
+int was_already_in_bfe = 0;
+