Esempio n. 1
0
/**
 * perform a function call
 * called from "hier11", this routine will either call the named
 * function, or if the supplied ptr is zero, will call the contents
 * of HL
 * @param ptr name of the function
 */
void callfunction(char *ptr) {
    int     nargs;

    nargs = 0;
    blanks ();
    if (ptr == 0)
        gen_push (HL_REG);
    while (!streq (line + lptr, ")")) {
        if (endst ())
            break;
        expression (NO);
        if (ptr == 0)
            gen_swap_stack ();
        gen_push (HL_REG);
        nargs = nargs + INTSIZE;
        if (!match (","))
            break;
    }
    needbrack (")");
    if (aflag)
        gnargs(nargs / INTSIZE);
    if (ptr)
        gen_call (ptr);
    else
        callstk ();
    stkp = gen_modify_stack (stkp + nargs);
}
Esempio n. 2
0
/**
 * "switch" statement
 */
void doswitch(void) {
        WHILE ws;
        WHILE *ptr;

        ws.symbol_idx = local_table_index;
        ws.stack_pointer = stkp;
        ws.type = WSSWITCH;
        ws.case_test = swstp;
        ws.body_tab = getlabel ();
        ws.incr_def = ws.while_exit = getlabel ();
        addwhile (&ws);
        gen_immediate ();
        print_label (ws.body_tab);
        newline ();
        gen_push (HL_REG);
        needbrack ("(");
        expression (YES);
        needbrack (")");
        stkp = stkp + INTSIZE;  // '?case' will adjust the stack
        gen_jump_case ();
        statement (NO);
        ptr = readswitch ();
        gen_jump (ptr->while_exit);
        dumpsw (ptr);
        generate_label (ptr->while_exit);
        local_table_index = ptr->symbol_idx;
        stkp = gen_modify_stack (ptr->stack_pointer);
        swstp = ptr->case_test;
        delwhile ();
}
Esempio n. 3
0
/**
 * divide the primary register by INTSIZE, never used
 */
void gen_divide_by_two(void) {
    gen_push(HL_REG);        /* push primary in prep for gasr */
    gen_immediate ();
    output_number (1);
    newline ();
    gen_arithm_shift_right ();  /* divide by two */
}
Esempio n. 4
0
/**
 * "switch" statement
 */
doswitch() {
        loop_t loop;
        loop_t *ptr;

        loop.symbol_idx = local_table_index;
        loop.stack_pointer = stkp;
        loop.type = WSSWITCH;
        loop.test_label = swstp;
        loop.body_label = getlabel ();
        loop.cont_label = loop.exit_label = getlabel ();
        addloop (&loop);
        gen_immediate_a ();
        print_label (loop.body_label);
        newline ();
        gen_push ();
        needbrack ("(");
        expression (YES);
        needbrack (")");
        stkp = stkp + INTSIZE;  // '?case' will adjust the stack
        gen_jump_case ();
        statement (NO);
        ptr = readswitch ();
        gen_jump (ptr->exit_label);
        dumpsw (ptr);
        generate_label (ptr->exit_label);
        local_table_index = ptr->symbol_idx;
        stkp = gen_modify_stack (ptr->stack_pointer);
        swstp = ptr->test_label;
        delloop ();
}
Esempio n. 5
0
AMODE    *temp_float(void)
/*
 *      allocate a temporary address register and return it's
 *      addressing mode.
 */
{       AMODE    *ap;
        ap = xalloc(sizeof(AMODE));
        ap->mode = am_freg;
        ap->preg = next_float % cf_freefloat;
        if( next_float > max_float )
                {
                gen_push(ap->preg,am_freg,0);
								fregs[ap->preg] = 1;
								regstack[rsdepth++] = ap->preg+16;
                max_addr = next_float;
                }
        ++next_float;
        return ap;
}
Esempio n. 6
0
AMODE    *temp_addr(void)
/*
 *      allocate a temporary address register and return it's
 *      addressing mode.
 */
{       AMODE    *ap;
        ap = xalloc(sizeof(AMODE));
        ap->mode = am_areg;
        ap->preg = next_addr % cf_freeaddress;
        if( next_addr > max_addr )
                {
                gen_push(ap->preg,am_areg,0);
								aregs[ap->preg] = 1;
								regstack[rsdepth++] = ap->preg+8;
                max_addr = next_addr;
                }
        ++next_addr;
        return ap;
}
Esempio n. 7
0
AMODE    *temp_data(void)
/*
 *      allocate a temporary data register and return it's
 *      addressing mode.
 */
{       AMODE    *ap;
        ap = xalloc(sizeof(AMODE));
        ap->mode = am_dreg;
        ap->preg = next_data % cf_freedata;
        if( next_data > max_data )
                {
                gen_push(ap->preg,am_dreg,0);
								dregs[ap->preg] = 1;
								regstack[rsdepth++] = ap->preg;
                max_data = next_data;
                }
        ++next_data;
        return ap;
}
Esempio n. 8
0
void Compiler::handle_ik_ls(const JInst& jinst) {
    switch(jinst.opcode) {
    case OPCODE_ICONST_M1:  gen_push((int)-1); break;
    case OPCODE_ICONST_0:   gen_push((int)0);   break;
    case OPCODE_ICONST_1:   gen_push((int)1);   break;
    case OPCODE_ICONST_2:   gen_push((int)2);   break;
    case OPCODE_ICONST_3:   gen_push((int)3);   break;
    case OPCODE_ICONST_4:   gen_push((int)4);   break;
    case OPCODE_ICONST_5:   gen_push((int)5);   break;

    case OPCODE_LCONST_0:   gen_push((jlong)0); break;
    case OPCODE_LCONST_1:   gen_push((jlong)1); break;

    case OPCODE_FCONST_0:   gen_push(flt32, &g_fconst_0); break;
    case OPCODE_FCONST_1:   gen_push(flt32, &g_fconst_1); break;
    case OPCODE_FCONST_2:   gen_push(flt32, &g_fconst_2); break;

    case OPCODE_DCONST_0:   gen_push(dbl64, &g_dconst_0); break;
    case OPCODE_DCONST_1:   gen_push(dbl64, &g_dconst_1); break;

    case OPCODE_LDC:
    case OPCODE_LDC_W:
    case OPCODE_LDC2_W:
        gen_ldc();
        break;
    case OPCODE_SIPUSH:
        gen_push((int)(short)(unsigned short)jinst.op0);
        break;
    case OPCODE_BIPUSH:
        gen_push((int)(char)(unsigned char)jinst.op0);
        break;

    case OPCODE_ASTORE:
        assert(m_jframe->top() == jobj || m_jframe->top() == jretAddr);
        gen_st(m_jframe->top(), jinst.op0);
        break;
    case OPCODE_ISTORE:     gen_st(i32, jinst.op0); break;
    case OPCODE_LSTORE:     gen_st(i64, jinst.op0); break;

    case OPCODE_FSTORE:     gen_st(flt32, jinst.op0); break;

    case OPCODE_DSTORE:     gen_st(dbl64, jinst.op0); break;

    case OPCODE_ISTORE_0:
    case OPCODE_ISTORE_1:
    case OPCODE_ISTORE_2:
    case OPCODE_ISTORE_3:
        gen_st(i32, jinst.opcode-OPCODE_ISTORE_0);
        break;
    case OPCODE_LSTORE_0:
    case OPCODE_LSTORE_1:
    case OPCODE_LSTORE_2:
    case OPCODE_LSTORE_3:
        gen_st(i64, jinst.opcode-OPCODE_LSTORE_0);
        break;
    case OPCODE_FSTORE_0:
    case OPCODE_FSTORE_1:
    case OPCODE_FSTORE_2:
    case OPCODE_FSTORE_3:
        gen_st(flt32, jinst.opcode-OPCODE_FSTORE_0);
        break;
    case OPCODE_DSTORE_0:
    case OPCODE_DSTORE_1:
    case OPCODE_DSTORE_2:
    case OPCODE_DSTORE_3:
        gen_st(dbl64, jinst.opcode-OPCODE_DSTORE_0);
        break;
    case OPCODE_ASTORE_0:
    case OPCODE_ASTORE_1:
    case OPCODE_ASTORE_2:
    case OPCODE_ASTORE_3:
        assert(m_jframe->top() == jobj || m_jframe->top() == jretAddr);
        gen_st(m_jframe->top(), jinst.opcode-OPCODE_ASTORE_0);
        break;

    case OPCODE_ILOAD:      gen_ld(i32, jinst.op0);   break;
    case OPCODE_LLOAD:      gen_ld(i64, jinst.op0);   break;

    case OPCODE_FLOAD:      gen_ld(flt32, jinst.op0); break;

    case OPCODE_DLOAD:      gen_ld(dbl64, jinst.op0); break;
    case OPCODE_ALOAD:      gen_ld(jobj, jinst.op0);  break;

    case OPCODE_ILOAD_0:
    case OPCODE_ILOAD_1:
    case OPCODE_ILOAD_2:
    case OPCODE_ILOAD_3:
        gen_ld(i32, jinst.opcode-OPCODE_ILOAD_0);
        break;
    case OPCODE_LLOAD_0:
    case OPCODE_LLOAD_1:
    case OPCODE_LLOAD_2:
    case OPCODE_LLOAD_3:
        gen_ld(i64, jinst.opcode-OPCODE_LLOAD_0);
        break;
    case OPCODE_FLOAD_0:
    case OPCODE_FLOAD_1:
    case OPCODE_FLOAD_2:
    case OPCODE_FLOAD_3:
        gen_ld(flt32, jinst.opcode-OPCODE_FLOAD_0);
        break;
    case OPCODE_DLOAD_0:
    case OPCODE_DLOAD_1:
    case OPCODE_DLOAD_2:
    case OPCODE_DLOAD_3:
        gen_ld(dbl64, jinst.opcode-OPCODE_DLOAD_0);
        break;
    case OPCODE_ALOAD_0:
    case OPCODE_ALOAD_1:
    case OPCODE_ALOAD_2:
    case OPCODE_ALOAD_3:
        gen_ld(jobj, jinst.opcode-OPCODE_ALOAD_0);
        break;
    case OPCODE_ACONST_NULL:
        gen_push(jobj, NULL_REF);
        break;
    default:    assert(false); break;
    }
}
Esempio n. 9
0
void genreturn(SNODE *stmt, int flag)
/*
 *      generate a return statement.
 */
{       AMODE    *ap,*ap1;
				int size;
        if( stmt != 0 && stmt->exp != 0 ) {
                initstack();
								if (currentfunc->tp->btp && currentfunc->tp->btp->type != bt_void && (currentfunc->tp->btp->type == bt_struct || currentfunc->tp->btp->type == bt_union)) {
									size = currentfunc->tp->btp->size;
									ap = gen_expr(stmt->exp,F_ALL,4);
									if (!(save_mask & 0x40))
										gen_push(ESI,am_dreg,0);                                  
									if (!(save_mask & 0x80))
										gen_push(EDI,am_dreg,0);                                  
									if (prm_linkreg) {
										ap1 = xalloc(sizeof(AMODE));
										ap1->preg = EBP;
										ap1->mode = am_indisp;
										if (currentfunc->pascaldefn && currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM *) -1) 
											ap1->offset = makenode(en_icon,(char *)(currentfunc->tp->lst.head->value.i+((currentfunc->tp->lst.head->tp->size+3) &0xFFFFFFFCL)),0);
										else
											ap1->offset = makenode(en_icon,(char *)8,0);
									}
									else
										if (currentfunc->pascaldefn && currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM *) -1) 
											ap1 = make_stack(-stackdepth-framedepth-currentfunc->tp->lst.head->value.i-((currentfunc->tp->lst.head->tp->size+3) & 0xfffffffcL));
										else
											ap1 = make_stack(-stackdepth-framedepth);
									gen_code(op_mov,4,makedreg(ESI),ap);		                  
									gen_code(op_mov,4,makedreg(EDI),ap1);
									gen_code(op_mov,4,makedreg(EAX),makedreg(EDI));
									gen_code(op_mov,4,makedreg(ECX),make_immed(size));  
									gen_code(op_cld,0,0,0);
									gen_code(op_rep,1,0,0);                                   
									gen_code(op_movsb,1,0,0);		                              
									if (!(save_mask & 0x80))
										gen_pop(EDI,am_dreg,0);
									if (!(save_mask & 0x40))
										gen_pop(ESI,am_dreg,0);
								}
								else {
									size = currentfunc->tp->btp->size;
  	              ap = gen_expr(stmt->exp,F_DREG | F_FREG,size);
									if (size > 4) {
										if (ap->mode != am_freg)
											gen_code(op_fld,size,ap,0);
									}
            	    else
              	  		if( ap->mode != am_dreg || ap->preg != 0 )
                	        gen_code(op_mov,size,makedreg(0),ap);
                }
								freeop(ap);
				}
				if (flag) {
	        if( retlab != -1 )
                gen_label(retlab);
          if( fsave_mask != 0 )
						diag("Float restore in return");
					if (!prm_linkreg && lc_maxauto)
						gen_code(op_add,4,makedreg(ESP),make_immed(lc_maxauto));
					if (currentfunc->intflag) {
						gen_code(op_popad,0,0,0);
						if (prm_linkreg && (lc_maxauto || currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM *)-1)) {
							gen_code(op_leave,0,0,0);
						}
           	gen_code(op_iretd,0,0,0);
					}
					else {
           	if( save_mask != 0 )
							popregs(save_mask);
						if (prm_linkreg && (lc_maxauto || currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM *)-1)) {
							gen_code(op_leave,0,0,0);
						}
						if (currentfunc->pascaldefn) {
							long retsize = 0;
							if (currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM *)-1) {
								retsize = currentfunc->tp->lst.head->value.i+((currentfunc->tp->lst.head->tp->size + 3) & 0xfffffffcL);
								if (prm_linkreg)
									retsize -= 8;
							}		
							if (currentfunc->tp->btp && currentfunc->tp->btp->type != bt_void && (currentfunc->tp->btp->type == bt_struct || currentfunc->tp->btp->type == bt_union)) 
								retsize += 4;
							if (retsize) {
            		gen_code(op_ret,0,make_immed(retsize),0);
								return;
							}
						}		
            gen_code(op_ret,0,0,0);
					}
				}
        else {
					if (retlab == -1)
            retlab = nextlabel++;
          gen_code(op_jmp,0,make_label(retlab),0);
				}
}
Esempio n. 10
0
/**
 * declare local variables
 * works just like "declglb", but modifies machine stack and adds
 * symbol table entry with appropriate stack offset to find it again
 * @param typ
 * @param stclass
 * @param otag index of tag in tag_table
 */
void declare_local(int typ, int stclass, int otag) {
    int     k, j;
    char    sname[NAMESIZE];

    FOREVER {
        FOREVER {
            if (endst())
                return;
            if (match("*"))
                j = POINTER;
            else
                j = VARIABLE;
            if (!symname(sname))
                illname();
            if (-1 != find_locale(sname))
                multidef (sname);
            if (match("[")) {
                k = needsub();
                if (k) {
                    j = ARRAY;
                    if (typ & CINT) {
                        k = k * INTSIZE;
                    } else if (typ == STRUCT) {
                        k = k * tag_table[otag].size;
                    }
                } else {
                    j = POINTER;
                    k = INTSIZE;
                }
            } else {
                if (j == POINTER) {
                    k = INTSIZE;
                } else {
                    switch (typ) {
                        case CCHAR:
                        case UCHAR:
                            k = 1;
                            break;
                        case STRUCT:
                            k = tag_table[otag].size;
                            break;
                        default:
                            k = INTSIZE;
                    }
                }
            }
            if (stclass == LSTATIC) {
                add_local(sname, j, typ, k, LSTATIC);
                break;
            }
            if (stclass == REGISTER) {
                int r = gen_register(j, k, typ);
                if (r != -1) {
                    add_local(sname, j, typ, r, REGISTER);
                    break;
                }
            }
            if (match("=")) {
                gen_modify_stack(stkp);
                expression(0);
                gen_push(0);
            } else
                stkp = gen_defer_modify_stack(stkp - k);
            add_local(sname, j, typ, stkp, AUTO);
            break;
        }
        if (!match(","))
            return;
    }
}
Esempio n. 11
0
void gen()
{
	int i, j, n;

	/* so far, we have no moves for the current ply */
	first_move[ply + 1] = first_move[ply];

	for (i = 0; i < 64; ++i)
		if (color[i] == side) {
			if (piece[i] == PAWN) {
				if (side == LIGHT) {
					if (COL(i) != 0 && color[i - 9] == DARK)
						gen_push(i, i - 9, 17);
					if (COL(i) != 7 && color[i - 7] == DARK)
						gen_push(i, i - 7, 17);
					if (color[i - 8] == EMPTY) {
						gen_push(i, i - 8, 16);
						if (i >= 48 && color[i - 16] == EMPTY)
							gen_push(i, i - 16, 24);
					}
				}
				else {
					if (COL(i) != 0 && color[i + 7] == LIGHT)
						gen_push(i, i + 7, 17);
					if (COL(i) != 7 && color[i + 9] == LIGHT)
						gen_push(i, i + 9, 17);
					if (color[i + 8] == EMPTY) {
						gen_push(i, i + 8, 16);
						if (i <= 15 && color[i + 16] == EMPTY)
							gen_push(i, i + 16, 24);
					}
				}
			}
			else
				for (j = 0; j < offsets[piece[i]]; ++j)
					for (n = i;;) {
						n = mailbox[mailbox64[n] + offset[piece[i]][j]];
						if (n == -1)
							break;
						if (color[n] != EMPTY) {
							if (color[n] == xside)
								gen_push(i, n, 1);
							break;
						}
						gen_push(i, n, 0);
						if (!slide[piece[i]])
							break;
					}
		}

	/* generate castle moves */
	if (side == LIGHT) {
		if (castle & 1)
			gen_push(E1, G1, 2);
		if (castle & 2)
			gen_push(E1, C1, 2);
	}
	else {
		if (castle & 4)
			gen_push(E8, G8, 2);
		if (castle & 8)
			gen_push(E8, C8, 2);
	}
	
	/* generate en passant moves */
	if (ep != -1) {
		if (side == LIGHT) {
			if (COL(ep) != 0 && color[ep + 7] == LIGHT && piece[ep + 7] == PAWN)
				gen_push(ep + 7, ep, 21);
			if (COL(ep) != 7 && color[ep + 9] == LIGHT && piece[ep + 9] == PAWN)
				gen_push(ep + 9, ep, 21);
		}
		else {
			if (COL(ep) != 0 && color[ep - 9] == DARK && piece[ep - 9] == PAWN)
				gen_push(ep - 9, ep, 21);
			if (COL(ep) != 7 && color[ep - 7] == DARK && piece[ep - 7] == PAWN)
				gen_push(ep - 7, ep, 21);
		}
	}
}
Esempio n. 12
0
void gen_caps()
{
	int i, j, n;

	first_move[ply + 1] = first_move[ply];
	for (i = 0; i < 64; ++i)
		if (color[i] == side) {
			if (piece[i]==PAWN) {
				if (side == LIGHT) {
					if (COL(i) != 0 && color[i - 9] == DARK)
						gen_push(i, i - 9, 17);
					if (COL(i) != 7 && color[i - 7] == DARK)
						gen_push(i, i - 7, 17);
					if (i <= 15 && color[i - 8] == EMPTY)
						gen_push(i, i - 8, 16);
				}
				if (side == DARK) {
					if (COL(i) != 0 && color[i + 7] == LIGHT)
						gen_push(i, i + 7, 17);
					if (COL(i) != 7 && color[i + 9] == LIGHT)
						gen_push(i, i + 9, 17);
					if (i >= 48 && color[i + 8] == EMPTY)
						gen_push(i, i + 8, 16);
				}
			}
			else
				for (j = 0; j < offsets[piece[i]]; ++j)
					for (n = i;;) {
						n = mailbox[mailbox64[n] + offset[piece[i]][j]];
						if (n == -1)
							break;
						if (color[n] != EMPTY) {
							if (color[n] == xside)
								gen_push(i, n, 1);
							break;
						}
						if (!slide[piece[i]])
							break;
					}
		}
	if (ep != -1) {
		if (side == LIGHT) {
			if (COL(ep) != 0 && color[ep + 7] == LIGHT && piece[ep + 7] == PAWN)
				gen_push(ep + 7, ep, 21);
			if (COL(ep) != 7 && color[ep + 9] == LIGHT && piece[ep + 9] == PAWN)
				gen_push(ep + 9, ep, 21);
		}
		else {
			if (COL(ep) != 0 && color[ep - 9] == DARK && piece[ep - 9] == PAWN)
				gen_push(ep - 9, ep, 21);
			if (COL(ep) != 7 && color[ep - 7] == DARK && piece[ep - 7] == PAWN)
				gen_push(ep - 7, ep, 21);
		}
	}
}