void C1_MacroAssembler::allocate(Register RDX_size_in_bytes, Register RCX_element_count_ekid, Register RSI_kid, Register RAX_oop, address alloc_stub, Label &slow_case) { // RDX: size in bytes // RCX: (EKID<<32 | element count) // RSI: kid assert0( RDX == RDX_size_in_bytes ); assert0( RCX == RCX_element_count_ekid ); assert0( RSI == RSI_kid ); NativeAllocationTemplate::fill(this, alloc_stub); assert0( RAX == RAX_oop ); // Z - failed, RAX - blown, RDX, RCX, RSI all preserved for the slow-path. // NZ- OK, R09- new oop, stripped; RAX - new oop w/mark, R10- preserved as ary length jeq (slow_case); verify_not_null_oop(RAX_oop, MacroAssembler::OopVerify_NewOop); // Fall into the next code, with RAX holding correct value }
CompileOutput *Compiler::Compile(AMXRef amx) { Prepare(amx); Disassembler disasm(amx); Instruction instr; bool error = false; while (!error && disasm.Decode(instr, error)) { if (!Process(instr)) { error = true; break; } switch (instr.opcode().GetId()) { case OP_LOAD_PRI: load_pri(instr.operand()); break; case OP_LOAD_ALT: load_alt(instr.operand()); break; case OP_LOAD_S_PRI: load_s_pri(instr.operand()); break; case OP_LOAD_S_ALT: load_s_alt(instr.operand()); break; case OP_LREF_PRI: lref_pri(instr.operand()); break; case OP_LREF_ALT: lref_alt(instr.operand()); break; case OP_LREF_S_PRI: lref_s_pri(instr.operand()); break; case OP_LREF_S_ALT: lref_s_alt(instr.operand()); break; case OP_LOAD_I: load_i(); break; case OP_LODB_I: lodb_i(instr.operand()); break; case OP_CONST_PRI: const_pri(instr.operand()); break; case OP_CONST_ALT: const_alt(instr.operand()); break; case OP_ADDR_PRI: addr_pri(instr.operand()); break; case OP_ADDR_ALT: addr_alt(instr.operand()); break; case OP_STOR_PRI: stor_pri(instr.operand()); break; case OP_STOR_ALT: stor_alt(instr.operand()); break; case OP_STOR_S_PRI: stor_s_pri(instr.operand()); break; case OP_STOR_S_ALT: stor_s_alt(instr.operand()); break; case OP_SREF_PRI: sref_pri(instr.operand()); break; case OP_SREF_ALT: sref_alt(instr.operand()); break; case OP_SREF_S_PRI: sref_s_pri(instr.operand()); break; case OP_SREF_S_ALT: sref_s_alt(instr.operand()); break; case OP_STOR_I: stor_i(); break; case OP_STRB_I: strb_i(instr.operand()); break; case OP_LIDX: lidx(); break; case OP_LIDX_B: lidx_b(instr.operand()); break; case OP_IDXADDR: idxaddr(); break; case OP_IDXADDR_B: idxaddr_b(instr.operand()); break; case OP_ALIGN_PRI: align_pri(instr.operand()); break; case OP_ALIGN_ALT: align_alt(instr.operand()); break; case OP_LCTRL: lctrl(instr.operand(), instr.address() + instr.size()); break; case OP_SCTRL: sctrl(instr.operand()); break; case OP_MOVE_PRI: move_pri(); break; case OP_MOVE_ALT: move_alt(); break; case OP_XCHG: xchg(); break; case OP_PUSH_PRI: push_pri(); break; case OP_PUSH_ALT: push_alt(); break; case OP_PUSH_C: push_c(instr.operand()); break; case OP_PUSH: push(instr.operand()); break; case OP_PUSH_S: push_s(instr.operand()); break; case OP_POP_PRI: pop_pri(); break; case OP_POP_ALT: pop_alt(); break; case OP_STACK: // value stack(instr.operand()); break; case OP_HEAP: heap(instr.operand()); break; case OP_PROC: proc(); break; case OP_RET: ret(); break; case OP_RETN: retn(); break; case OP_JUMP_PRI: jump_pri(); break; case OP_CALL: case OP_JUMP: case OP_JZER: case OP_JNZ: case OP_JEQ: case OP_JNEQ: case OP_JLESS: case OP_JLEQ: case OP_JGRTR: case OP_JGEQ: case OP_JSLESS: case OP_JSLEQ: case OP_JSGRTR: case OP_JSGEQ: { cell dest = instr.operand() - reinterpret_cast<cell>(amx.code()); switch (instr.opcode().GetId()) { case OP_CALL: call(dest); break; case OP_JUMP: jump(dest); break; case OP_JZER: jzer(dest); break; case OP_JNZ: jnz(dest); break; case OP_JEQ: jeq(dest); break; case OP_JNEQ: jneq(dest); break; case OP_JLESS: jless(dest); break; case OP_JLEQ: jleq(dest); break; case OP_JGRTR: jgrtr(dest); break; case OP_JGEQ: jgeq(dest); break; case OP_JSLESS: jsless(dest); break; case OP_JSLEQ: jsleq(dest); break; case OP_JSGRTR: jsgrtr(dest); break; case OP_JSGEQ: jsgeq(dest); break; } break; } case OP_SHL: shl(); break; case OP_SHR: shr(); break; case OP_SSHR: sshr(); break; case OP_SHL_C_PRI: shl_c_pri(instr.operand()); break; case OP_SHL_C_ALT: shl_c_alt(instr.operand()); break; case OP_SHR_C_PRI: shr_c_pri(instr.operand()); break; case OP_SHR_C_ALT: shr_c_alt(instr.operand()); break; case OP_SMUL: smul(); break; case OP_SDIV: sdiv(); break; case OP_SDIV_ALT: sdiv_alt(); break; case OP_UMUL: umul(); break; case OP_UDIV: udiv(); break; case OP_UDIV_ALT: udiv_alt(); break; case OP_ADD: add(); break; case OP_SUB: sub(); break; case OP_SUB_ALT: sub_alt(); break; case OP_AND: and_(); break; case OP_OR: or_(); break; case OP_XOR: xor_(); break; case OP_NOT: not_(); break; case OP_NEG: neg(); break; case OP_INVERT: invert(); break; case OP_ADD_C: add_c(instr.operand()); break; case OP_SMUL_C: smul_c(instr.operand()); break; case OP_ZERO_PRI: zero_pri(); break; case OP_ZERO_ALT: zero_alt(); break; case OP_ZERO: zero(instr.operand()); break; case OP_ZERO_S: zero_s(instr.operand()); break; case OP_SIGN_PRI: sign_pri(); break; case OP_SIGN_ALT: sign_alt(); break; case OP_EQ: eq(); break; case OP_NEQ: neq(); break; case OP_LESS: less(); break; case OP_LEQ: leq(); break; case OP_GRTR: grtr(); break; case OP_GEQ: geq(); break; case OP_SLESS: sless(); break; case OP_SLEQ: sleq(); break; case OP_SGRTR: sgrtr(); break; case OP_SGEQ: sgeq(); break; case OP_EQ_C_PRI: eq_c_pri(instr.operand()); break; case OP_EQ_C_ALT: eq_c_alt(instr.operand()); break; case OP_INC_PRI: inc_pri(); break; case OP_INC_ALT: inc_alt(); break; case OP_INC: inc(instr.operand()); break; case OP_INC_S: inc_s(instr.operand()); break; case OP_INC_I: inc_i(); break; case OP_DEC_PRI: dec_pri(); break; case OP_DEC_ALT: dec_alt(); break; case OP_DEC: dec(instr.operand()); break; case OP_DEC_S: dec_s(instr.operand()); break; case OP_DEC_I: dec_i(); break; case OP_MOVS: movs(instr.operand()); break; case OP_CMPS: cmps(instr.operand()); break; case OP_FILL: fill(instr.operand()); break; case OP_HALT: halt(instr.operand()); break; case OP_BOUNDS: bounds(instr.operand()); break; case OP_SYSREQ_PRI: sysreq_pri(); break; case OP_SYSREQ_C: { const char *name = amx.GetNativeName(instr.operand()); if (name == 0) { error = true; } else { sysreq_c(instr.operand(), name); } break; } case OP_SYSREQ_D: { const char *name = amx.GetNativeName(amx.FindNative(instr.operand())); if (name == 0) { error = true; } else { sysreq_d(instr.operand(), name); } break; } case OP_SWITCH: switch_(CaseTable(amx, instr.operand())); break; case OP_CASETBL: casetbl(); break; case OP_SWAP_PRI: swap_pri(); break; case OP_SWAP_ALT: swap_alt(); break; case OP_PUSH_ADR: push_adr(instr.operand()); break; case OP_NOP: nop(); break; case OP_BREAK: break_(); break; default: error = true; } } if (error && error_handler_ != 0) { error_handler_->Execute(instr); } return Finish(error); }
int encode_op(char *opcode, char *op_data) { int rd,rs,rt,imm,funct,shaft,target; char tmp[256]; const char *fi = "%s %d"; const char *fg = "%s %%g%d"; const char *ff = "%s %%f%d"; const char *fl = "%s %s"; const char *fgi = "%s %%g%d, %d"; const char *fgl = "%s %%g%d, %s"; const char *fgg = "%s %%g%d, %%g%d"; const char *fggl = "%s %%g%d, %%g%d, %s"; const char *fggi = "%s %%g%d, %%g%d, %d"; const char *fggg = "%s %%g%d, %%g%d, %%g%d"; const char *fff = "%s %%f%d, %%f%d"; const char *fgf = "%s %%g%d, %%f%d"; const char *ffg = "%s %%f%d, %%g%d"; const char *fffl = "%s %%f%d, %%f%d, %s"; const char *ffff = "%s %%f%d, %%f%d, %%f%d"; const char *ffgi = "%s %%f%d, %%g%d, %d"; const char *ffgg = "%s %%f%d, %%g%d, %%g%d"; char lname[256]; shaft = funct = target = 0; if(strcmp(opcode, "mvhi") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return mvhi(rs,0,imm); } if(strcmp(opcode, "mvlo") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return mvlo(rs,0,imm); } if(strcmp(opcode, "add") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return add(rs,rt,rd,0); } if(strcmp(opcode, "nor") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return nor(rs,rt,rd,0); } if(strcmp(opcode, "sub") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return sub(rs,rt,rd,0); } if(strcmp(opcode, "mul") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return mul(rs,rt,rd,0); } if(strcmp(opcode, "addi") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return addi(rs,rt,imm); } if(strcmp(opcode, "subi") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return subi(rs,rt,imm); } if(strcmp(opcode, "muli") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return muli(rs,rt,imm); } if(strcmp(opcode, "input") == 0){ if(sscanf(op_data, fg, tmp, &rd) == 2) return input(0,0,rd,0); } if(strcmp(opcode, "inputw") == 0){ if(sscanf(op_data, fg, tmp, &rd) == 2) return inputw(0,0,rd,0); } if(strcmp(opcode, "inputf") == 0){ if(sscanf(op_data, ff, tmp, &rd) == 2) return inputf(0,0,rd,0); } if(strcmp(opcode, "output") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return output(rs,0,0,0); } if(strcmp(opcode, "outputw") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return outputw(rs,0,0,0); } if(strcmp(opcode, "outputf") == 0){ if(sscanf(op_data, ff, tmp, &rs) == 2) return outputf(rs,0,0,0); } if(strcmp(opcode, "and") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return _and(rs,rt,rd,0); } if(strcmp(opcode, "or") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return _or(rs,rt,rd,0); } if(strcmp(opcode, "sll") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return sll(rs,rt,rd,0); } if(strcmp(opcode, "srl") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return srl(rs,rt,rd,0); } if(strcmp(opcode, "slli") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return slli(rs,rt,imm); } if(strcmp(opcode, "srli") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return srli(rs,rt,imm); } if(strcmp(opcode, "b") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return b(rs,0,0,0); } if(strcmp(opcode, "jmp") == 0){ if(sscanf(op_data, fl, tmp, lname) == 2) { strcpy(label_name[label_cnt],lname); return jmp(label_cnt++); } } if(strcmp(opcode, "jeq") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jeq(rs,rt,label_cnt++); } } if(strcmp(opcode, "jne") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jne(rs,rt,label_cnt++); } } if(strcmp(opcode, "jlt") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jlt(rs,rt,label_cnt++); } } if(strcmp(opcode, "jle") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jle(rs,rt,label_cnt++); } } if(strcmp(opcode, "call") == 0){ if(sscanf(op_data, fl, tmp, lname) == 2) { strcpy(label_name[label_cnt],lname); return call(label_cnt++); } } if(strcmp(opcode, "callR") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return callr(rs,0,0,0); } if(strcmp(opcode, "return") == 0){ return _return(0); } if(strcmp(opcode, "ld") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return ld(rs,rt,rd,0); } if(strcmp(opcode, "ldi") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return ldi(rs,rt,imm); } if(strcmp(opcode, "ldlr") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return ldlr(rs,0,imm); } if(strcmp(opcode, "fld") == 0){ if(sscanf(op_data, ffgg, tmp, &rd, &rs,&rt) == 4) return fld(rs,rt,rd,0); } if(strcmp(opcode, "st") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return st(rs,rt,rd,0); } if(strcmp(opcode, "sti") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return sti(rs,rt,imm); } if(strcmp(opcode, "stlr") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return stlr(rs,0,imm); } if(strcmp(opcode, "fst") == 0){ if(sscanf(op_data, ffgg, tmp, &rd, &rs,&rt) == 4) return fst(rs,rt,rd,0); } if(strcmp(opcode, "fadd") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fadd(rs,rt,rd,0); } if(strcmp(opcode, "fsub") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fsub(rs,rt,rd,0); } if(strcmp(opcode, "fmul") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fmul(rs,rt,rd,0); } if(strcmp(opcode, "fdiv") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fdiv(rs,rt,rd,0); } if(strcmp(opcode, "fsqrt") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return fsqrt(rs,0,rd,0); } if(strcmp(opcode, "fabs") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return _fabs(rs,0,rd,0); } if(strcmp(opcode, "fmov") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return fmov(rs,0,rd,0); } if(strcmp(opcode, "fneg") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return fneg(rs,0,rd,0); } if(strcmp(opcode, "fldi") == 0){ if(sscanf(op_data, ffgi, tmp, &rt, &rs, &imm) == 4) return fldi(rs,rt,imm); } if(strcmp(opcode, "fsti") == 0){ if(sscanf(op_data, ffgi, tmp, &rt, &rs, &imm) == 4) return fsti(rs,rt,imm); } if(strcmp(opcode, "fjeq") == 0){ if(sscanf(op_data, fffl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return fjeq(rs,rt,label_cnt++); } } if(strcmp(opcode, "fjlt") == 0){ if(sscanf(op_data, fffl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return fjlt(rs,rt,label_cnt++); } } if(strcmp(opcode, "halt") == 0){ return halt(0,0,0,0); } if(strcmp(opcode, "setL") == 0){ if(sscanf(op_data, fgl, tmp, &rd, lname) == 3) { strcpy(label_name[label_cnt],lname); return setl(0,rd,label_cnt++); } } if(strcmp(opcode, "padd") == 0){ if(sscanf(op_data, fgi, tmp, &rt, &imm) == 3) { return padd(0,rt,imm); } } if(strcmp(opcode, "link") == 0){ if(sscanf(op_data, fi, tmp, &imm) == 2) { return link(0,0,imm); } } if(strcmp(opcode, "movlr") == 0){ return movlr(0,0,0,0); } if(strcmp(opcode, "btmplr") == 0){ return btmplr(0,0,0,0); } /* if(strcmp(opcode, "padd") == 0){ if(sscanf(op_data, fgg, tmp, &rd, &rt) == 3) { return padd(0,rt,d,0); } } */ return -1; }