| 72 | } |
| 73 | |
| 74 | void JitCompiler::EmitRET() |
| 75 | { |
| 76 | using namespace asmjit; |
| 77 | if (B == REGT_NIL) |
| 78 | { |
| 79 | EmitPopFrame(); |
| 80 | X86Gp vReg = newTempInt32(); |
| 81 | cc.mov(vReg, 0); |
| 82 | cc.ret(vReg); |
| 83 | } |
| 84 | else |
| 85 | { |
| 86 | int a = A; |
| 87 | int retnum = a & ~RET_FINAL; |
| 88 | |
| 89 | X86Gp reg_retnum = newTempInt32(); |
| 90 | X86Gp location = newTempIntPtr(); |
| 91 | Label L_endif = cc.newLabel(); |
| 92 | |
| 93 | cc.mov(reg_retnum, retnum); |
| 94 | cc.cmp(reg_retnum, numret); |
| 95 | cc.jge(L_endif); |
| 96 | |
| 97 | cc.mov(location, x86::ptr(ret, retnum * sizeof(VMReturn))); |
| 98 | |
| 99 | int regtype = B; |
| 100 | int regnum = C; |
| 101 | switch (regtype & REGT_TYPE) |
| 102 | { |
| 103 | case REGT_INT: |
| 104 | if (regtype & REGT_KONST) |
| 105 | cc.mov(x86::dword_ptr(location), konstd[regnum]); |
| 106 | else |
| 107 | cc.mov(x86::dword_ptr(location), regD[regnum]); |
| 108 | break; |
| 109 | case REGT_FLOAT: |
| 110 | if (regtype & REGT_KONST) |
| 111 | { |
| 112 | auto tmp = newTempInt64(); |
| 113 | if (regtype & REGT_MULTIREG4) |
| 114 | { |
| 115 | cc.mov(tmp, (((int64_t*)konstf)[regnum])); |
| 116 | cc.mov(x86::qword_ptr(location), tmp); |
| 117 | |
| 118 | cc.mov(tmp, (((int64_t*)konstf)[regnum + 1])); |
| 119 | cc.mov(x86::qword_ptr(location, 8), tmp); |
| 120 | |
| 121 | cc.mov(tmp, (((int64_t*)konstf)[regnum + 2])); |
| 122 | cc.mov(x86::qword_ptr(location, 16), tmp); |
| 123 | |
| 124 | cc.mov(tmp, (((int64_t*)konstf)[regnum + 3])); |
| 125 | cc.mov(x86::qword_ptr(location, 24), tmp); |
| 126 | } |
| 127 | else if (regtype & REGT_MULTIREG3) |
| 128 | { |
| 129 | cc.mov(tmp, (((int64_t *)konstf)[regnum])); |
| 130 | cc.mov(x86::qword_ptr(location), tmp); |
| 131 | |