Ejemplo n.º 1
0
/* assign input vector */
void assign_input_affix ()
{   int nr = popi ();
    affix_node affx = popa ();
    value new_val = my_ivals[nr];

    if (affx -> val != value_nil)
    {   if (equal_value (new_val, affx -> val)) callq ();
    }
    else
    {   affx -> val = rdup_value (new_val);
        if (affx -> mfunc != NULL)
        {   /* check metadefinition */
            pushv (new_val);
            pushq (affx -> mfunc);
            callq ();
            pop (2);
        }
        else callq ();
        rfre_value (new_val);
        affx -> val = value_nil;
    };
    pusha (affx);
    pushi (nr);
    pushq (assign_input_affix);
};
Ejemplo n.º 2
0
void collect_output_affix ()
{   int nr = popi ();
    affix_node affx = popa ();
    value new_val = affx -> val;
    check_for_space ();
    my_cvals[nrofparses][nr] = rdup_value (new_val);
    callq ();
    pusha (affx);
    pushi (nr);
    pushq (collect_output_affix);
};
Ejemplo n.º 3
0
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
  if (!TraceMethodHandles)  return;
  BLOCK_COMMENT("trace_method_handle {");
  __ enter();
  __ andptr(rsp, -16); // align stack if needed for FPU state
  __ pusha();
  __ mov(rbx, rsp); // for retreiving saved_regs
  // Note: saved_regs must be in the entered frame for the
  // robust stack walking implemented in trace_method_handle_stub.

  // save FP result, valid at some call sites (adapter_opt_return_float, ...)
  __ increment(rsp, -2 * wordSize);
  if  (UseSSE >= 2) {
    __ movdbl(Address(rsp, 0), xmm0);
  } else if (UseSSE == 1) {
    __ movflt(Address(rsp, 0), xmm0);
  } else {
    __ fst_d(Address(rsp, 0));
  }

  // Incoming state:
  // rcx: method handle
  //
  // To avoid calling convention issues, build a record on the stack
  // and pass the pointer to that instead.
  __ push(rbp);               // entry_sp (with extra align space)
  __ push(rbx);               // pusha saved_regs
  __ push(rcx);               // mh
  __ push(rcx);               // slot for adaptername
  __ movptr(Address(rsp, 0), (intptr_t) adaptername);
  __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub_wrapper), rsp);
  __ increment(rsp, sizeof(MethodHandleStubArguments));

  if  (UseSSE >= 2) {
    __ movdbl(xmm0, Address(rsp, 0));
  } else if (UseSSE == 1) {
    __ movflt(xmm0, Address(rsp, 0));
  } else {
    __ fld_d(Address(rsp, 0));
  }
  __ increment(rsp, 2 * wordSize);

  __ popa();
  __ leave();
  BLOCK_COMMENT("} trace_method_handle");
}
Ejemplo n.º 4
0
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
  if (!TraceMethodHandles)  return;
  BLOCK_COMMENT("trace_method_handle {");
  __ push(rax);
  __ lea(rax, Address(rsp, wordSize*6)); // entry_sp
  __ pusha();
  // arguments:
  __ push(rbp);               // interpreter frame pointer
  __ push(rsi);               // saved_sp
  __ push(rax);               // entry_sp
  __ push(rcx);               // mh
  __ push(rcx);
  __ movptr(Address(rsp, 0), (intptr_t) adaptername);
  __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 5);
  __ popa();
  __ pop(rax);
  BLOCK_COMMENT("} trace_method_handle");
}
Ejemplo n.º 5
0
void getCode(InterCode node) {
	if(node == NULL)
		return;
	switch(node->kind) {
		case Assign: {
            Operand r = node->u.assign.right;
            Operand l = node->u.assign.left;
            if (r->kind == CONSTANT) {
                if (l->isPointer == false) {
                    fprintf(stream, "li $t1, %d\n", r->u.value);
                    insertSPADD(l);
                }
                else {
                    fprintf(stream, "li $t2 %d\n", r->u.value);
                    fprintf(stream, "lw $t3 %d($fp)\n", searchSPADD(l));
                    fprintf(stream, "add $t3, $t3, $fp\n");
                    fprintf(stream, "sw $t2 0($t3)\n");
                }
            }
            else {
                if (l->isPointer == false) {
                    //t=a
                    if (r->isPointer == false) {
                        fprintf(stream, "lw $t1 %d($fp)\n", searchSPADD(r));
                        insertSPADD(l);
                    }
                    //t=&a
                    else {
                        fprintf(stream, "li $t1, %d\n", searchSPADD(r));
                        insertSPADD(l);
                    }
                }
                //*t=a
                else {
                    fprintf(stream, "lw $t2 %d($fp)\n", searchSPADD(r));
                    fprintf(stream, "lw $t3 %d($fp)\n", searchSPADD(l));
                    fprintf(stream, "add $t3, $t3, $fp\n");
                    fprintf(stream, "sw $t2 0($t3)\n");
                }
            }
            break;
        }
        case BINOP: {
            Operand op1 = node->u.binop.op1;
            Operand op2 = node->u.binop.op2;
            char kind = node->u.binop.kind[0];
            //Load correct data to $t2 and $t3
            if (op1->kind == CONSTANT) {
                fprintf(stream, "li $t2 %d\n", op1->u.value);
            }
            else if(op1->isPointer == false){
                fprintf(stream, "lw $t2 %d($fp)\n", searchSPADD(op1));
            }
            else {
               // t = a + *t
                if (op1->kind == ADDRESS) {
                    fprintf(stream, "lw $t2 %d($fp)\n", searchSPADD(op1));
                    fprintf(stream, "add $t2, $t2, $fp\n");
                    fprintf(stream, "lw $t2 0($t2)\n");
                }
                else {
                    // t = a + &b
                    fprintf(stream, "li $t2, %d\n", searchSPADD(op1));
                }
            }
           
            if (op2->kind == CONSTANT) {
                fprintf(stream, "li $t3 %d\n", op2->u.value);
            }
            else if(op2->isPointer == false){
                fprintf(stream, "lw $t3 %d($fp)\n", searchSPADD(op2));
            }
            else {
               // t = a + *t
                if (op2->kind == ADDRESS) {
                    fprintf(stream, "lw $t3 %d($fp)\n", searchSPADD(op2));
                    fprintf(stream, "add $t3, $t3, $fp\n");
                    fprintf(stream, "lw $t3 0($t3)\n");
                }
                else {
                    // t = a + &b
                    fprintf(stream, "li $t3, %d\n", searchSPADD(op2));
                }
            }
            
            
            if (kind == '+') {
                fprintf(stream, "add $t1, $t2, $t3\n");
            }
            else if (kind == '-') {
                fprintf(stream, "sub $t1, $t2, $t3\n");
            }
            else if (kind == '*') {
                fprintf(stream, "mul $t1, $t2, $t3\n");
            }
            else if(kind == '/') {
                fprintf(stream, "div $t2, $t3\n");
                fprintf(stream, "mflo $t1\n");
            }
            insertSPADD(node->u.binop.result);
            break;
        }
        
        case UNARYOP: {
            Operand op = node->u.unaryop.op;
            char* kind = node->u.unaryop.kind;
            if (strcmp(kind, "LABEL") == 0) {
                fprintf(stream, "Label%d:\n", op->u.no);
            }
            else if(strcmp(kind, "GOTO") == 0) {
                fprintf(stream, "j Label%d\n", op->u.no);
            }
            else if(strcmp(kind, "READ") == 0) {
                fprintf(stream, "li $v0, 4\n");
                fprintf(stream, "la $a0, _prompt\n");
                fprintf(stream, "syscall\n");
                fprintf(stream, "li $v0, 5\n");
                fprintf(stream, "syscall\n");
                fprintf(stream, "move $t1, $v0\n");
                insertSPADD(node->u.unaryop.op);
            }
            else if(strcmp(kind, "WRITE") == 0) {
                if (node->u.unaryop.op->kind == CONSTANT) {
                    fprintf(stream, "li $a0 %d\n", node->u.unaryop.op->u.value);
                }
                else if(node->u.unaryop.op->isPointer == false) {
                    fprintf(stream,"lw $a0 %d($fp)\n",searchSPADD(node->u.unaryop.op));
                }
                else{
                    fprintf(stream,"lw $t1 %d($fp)\n",searchSPADD(node->u.unaryop.op));
                    fprintf(stream,"add $t3, $t1, $fp\n");
                    fprintf(stream,"lw $a0, 0($t3)\n");
                }
                fprintf(stream, "li $v0, 1\n");
                fprintf(stream, "syscall\n");
                fprintf(stream, "li $v0, 4\n");
                fprintf(stream, "la $a0, _ret\n");
                fprintf(stream, "syscall\n");
            }
            else if(strcmp(kind, "ARG") == 0) {
                pusha(&stack_arg, op);
            }
            break;
        }
            
        case If: {
            Operand op1 = node->u.ifop.op1;
            Operand op2 = node->u.ifop.op2;
            char* relop = node->u.ifop.relop;
            //Load correct data
            if (op1->kind == CONSTANT) {
                fprintf(stream, "li $t2 %d\n", op1->u.value);
            }
            else if(op1->isPointer == false){
                fprintf(stream, "lw $t2 %d($fp)\n", searchSPADD(op1));
            }
            else {
                // t = a + *t
                if (op1->kind == ADDRESS) {
                    fprintf(stream, "lw $t2 %d($fp)\n", searchSPADD(op1));
                    fprintf(stream, "add $t2, $t2, $fp\n");
                    fprintf(stream, "lw $t2 0($t2)\n");
                }
                else {
                    // t = a + &b
                    fprintf(stream, "li $t2, %d\n", searchSPADD(op1));
                }
            }
            
            if (op2->kind == CONSTANT) {
                fprintf(stream, "li $t3 %d\n", op2->u.value);
            }
            else if(op2->isPointer == false){
                fprintf(stream, "lw $t3 %d($fp)\n", searchSPADD(op2));
            }
            else {
                // t = a + *t
                if (op2->kind == ADDRESS) {
                    fprintf(stream, "lw $t3 %d($fp)\n", searchSPADD(op2));
                    fprintf(stream, "add $t3, $t3, $fp\n");
                    fprintf(stream, "lw $t3 0($t3)\n");
                }
                else {
                    // t = a + &b
                    fprintf(stream, "li $t3, %d\n", searchSPADD(op2));
                }
            }
            
            if (strcmp(relop, "==") == 0) {
                fprintf(stream, "beq $t2, $t3, ");
            }
            else if (strcmp(relop, "!=") == 0) {
                fprintf(stream, "bne $t2, $t3, ");
            }
            else if (strcmp(relop, ">") == 0) {
                fprintf(stream, "bgt $t2, $t3, ");
            }
            else if (strcmp(relop, "<") == 0) {
                fprintf(stream, "blt $t2, $t3, ");
            }
            else if (strcmp(relop, ">=") == 0) {
                fprintf(stream, "bge $t2, $t3, ");
            }
            else if (strcmp(relop, "<=") == 0) {
                fprintf(stream, "ble $t2, $t3, ");
            }
            fprintf(stream, "Label%d\n", node->u.ifop.op3->u.no);
            break;
        }
        
        case IRDEC: {
            SPADD add = (SPADD)malloc(sizeof(struct _SPADD));
            memset(add, 0, sizeof(struct _SPADD));
            add->op = node->u.dec.op;
            sp = sp -node->u.dec.size;
            add->addr = sp;
            add->next = spaddHead;
            spaddHead = add;
            break;
        }
            
        case CALL: {
            //Save the current sp
            push(&stack_func, sp);
            
            //Set arguments on the stack
            Operand arg = popa(&stack_arg);
            while (arg != NULL) {
                if (arg->kind != CONSTANT) {
                    //ARG *t i.e. func(a[5])
                    if (arg->isPointer == true) {
                        fprintf(stream, "lw $t1 %d($fp)\n", searchSPADD(arg));
                        fprintf(stream, "add $t1, $t1, $fp\n");
                        fprintf(stream, "lw $t1 0($t1)\n");
                    }
                    else {
                        fprintf(stream, "lw $t1 %d($fp)\n", searchSPADD(arg));
                    }
                }
                else {
                    fprintf(stream, "li $t1, %d\n", arg->u.value);
                }
                sp = sp - 4;
                fprintf(stream, "sw $t1 %d($fp)\n", sp);
                arg = popa(&stack_arg);
            }
            //Save $fp and $ra
            sp -= 4;
            fprintf(stream, "sw $fp %d($fp)\n", sp);
            sp -= 4;
            fprintf(stream, "sw $ra %d($fp)\n", sp);
            
            fprintf(stream, "addi $fp, $fp, %d\n", sp);
            fprintf(stream, "jal _%s\n", node->u.call.fun_name);
            //Restore
            sp = pop(&stack_func);
            fprintf(stream, "lw $ra 0($fp)\n");
            fprintf(stream, "lw $fp 4($fp)\n");
            //Deal with result
            fprintf(stream, "move $t1, $v0\n");
            insertSPADD(node->u.call.result);
            break;
        }
        case FUNC: {
            if (strcmp(node->u.function, "main") == 0) {
                fprintf(stream, "%s:\n", node->u.function);
                fprintf(stream, "move $fp $sp\n");
            }
            //Afraid of the function named "sub", which is the same with instruction sub
            else {
                fprintf(stream, "_%s:\n", node->u.function);
            }
            fprintf(stream, "addi $sp, $sp, -2048\n");
            sp = 0;
            break;
        }
        case RET: {
            //$sp is not used at all
            fprintf(stream, "addi $sp, $sp, 2048\n");
            if (node->u.returnc.op->kind == CONSTANT) {
                fprintf(stream, "li $v0 %d\n", node->u.returnc.op->u.value);
            }
            else {
                fprintf(stream,"lw $v0 %d($fp)\n",searchSPADD(node->u.returnc.op));
                if(node->u.returnc.op->isPointer == 1){
                    fprintf(stream,"add $t3, $tv0, $fp\n");
                    fprintf(stream,"lw $v0, 0($t3)\n");
                }
            }
			fprintf(stream,"jr $ra");
            break;
        }
        case PARAM: {
            int num_a = 0;
            for (InterCode t = node->next; t->kind == PARAM; t = t->next) {
                num_a++;
            }
            num_a += 2;//$ra And $fp
            fprintf(stream, "lw $t1 %d($fp)\n", num_a * 4);
            insertSPADD(node->u.call.result);
            break;
        }

    }
}