summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-07-31 12:40:09 -0400
committerGravatar bunnei2015-08-15 18:01:22 -0400
commitcfb354f11f55b940a2f4476f2b42c6813feb3f38 (patch)
treeb98090f91109d4061e611c72ab28834c992ff08e /src
parentShader: Initial implementation of x86_x64 JIT compiler for Pica vertex shaders. (diff)
downloadyuzu-cfb354f11f55b940a2f4476f2b42c6813feb3f38.tar.gz
yuzu-cfb354f11f55b940a2f4476f2b42c6813feb3f38.tar.xz
yuzu-cfb354f11f55b940a2f4476f2b42c6813feb3f38.zip
JIT: Support negative address offsets.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/shader_jit_x64.cpp51
1 files changed, 25 insertions, 26 deletions
diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp
index 00c57afec..d69f3a549 100644
--- a/src/video_core/shader/shader_jit_x64.cpp
+++ b/src/video_core/shader/shader_jit_x64.cpp
@@ -91,9 +91,10 @@ const JitFunction instr_table[64] = {
91// purposes, as documented below: 91// purposes, as documented below:
92 92
93/// Pointer to the uniform memory 93/// Pointer to the uniform memory
94static const X64Reg UNIFORMS = R10; 94static const X64Reg UNIFORMS = R9;
95/// The two 32-bit VS address offset registers set by the MOVA instruction 95/// The two 32-bit VS address offset registers set by the MOVA instruction
96static const X64Reg ADDROFFS_REG = R11; 96static const X64Reg ADDROFFS_REG_0 = R10;
97static const X64Reg ADDROFFS_REG_1 = R11;
97/// VS loop count register 98/// VS loop count register
98static const X64Reg LOOPCOUNT_REG = R12; 99static const X64Reg LOOPCOUNT_REG = R12;
99/// Current VS loop iteration number (we could probably use LOOPCOUNT_REG, but this quicker) 100/// Current VS loop iteration number (we could probably use LOOPCOUNT_REG, but this quicker)
@@ -162,21 +163,18 @@ void JitCompiler::Compile_SwizzleSrc(Instruction instr, unsigned src_num, Source
162 if (src_num == offset_src && instr.common.address_register_index != 0) { 163 if (src_num == offset_src && instr.common.address_register_index != 0) {
163 switch (instr.common.address_register_index) { 164 switch (instr.common.address_register_index) {
164 case 1: // address offset 1 165 case 1: // address offset 1
165 MOV(32, R(RBX), R(ADDROFFS_REG)); 166 MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_0, 1, src_offset));
166 break; 167 break;
167 case 2: // address offset 2 168 case 2: // address offset 2
168 MOV(64, R(RBX), R(ADDROFFS_REG)); 169 MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_1, 1, src_offset));
169 SHR(64, R(RBX), Imm8(32));
170 break; 170 break;
171 case 3: // adddress offet 3 171 case 3: // adddress offet 3
172 MOV(64, R(RBX), R(LOOPCOUNT_REG)); 172 MOVAPS(dest, MComplex(src_ptr, LOOPCOUNT_REG, 1, src_offset));
173 break; 173 break;
174 default: 174 default:
175 UNREACHABLE(); 175 UNREACHABLE();
176 break; 176 break;
177 } 177 }
178
179 MOVAPS(dest, MComplex(src_ptr, RBX, 1, src_offset));
180 } else { 178 } else {
181 // Load the source 179 // Load the source
182 MOVAPS(dest, MDisp(src_ptr, src_offset)); 180 MOVAPS(dest, MDisp(src_ptr, src_offset));
@@ -381,33 +379,34 @@ void JitCompiler::Compile_MOVA(Instruction instr) {
381 379
382 // Get result 380 // Get result
383 MOVQ_xmm(R(RAX), SRC1); 381 MOVQ_xmm(R(RAX), SRC1);
384 SHL(64, R(RAX), Imm8(4)); // Multiply by 16 to be used as an offset later
385 382
386 // Handle destination enable 383 // Handle destination enable
387 if (swiz.DestComponentEnabled(0) && swiz.DestComponentEnabled(1)) { 384 if (swiz.DestComponentEnabled(0) && swiz.DestComponentEnabled(1)) {
388 MOV(64, R(ADDROFFS_REG), R(RAX)); // Overwrite both 385 // Move and sign-extend low 32 bits
386 MOVSX(64, 32, ADDROFFS_REG_0, R(RAX));
387
388 // Move and sign-extend high 32 bits
389 SHR(64, R(RAX), Imm8(32));
390 MOVSX(64, 32, ADDROFFS_REG_1, R(RAX));
391
392 // Multiply by 16 to be used as an offset later
393 SHL(64, R(ADDROFFS_REG_0), Imm8(4));
394 SHL(64, R(ADDROFFS_REG_1), Imm8(4));
389 } else { 395 } else {
390 if (swiz.DestComponentEnabled(0)) { 396 if (swiz.DestComponentEnabled(0)) {
391 // Preserve Y-component 397 // Move and sign-extend low 32 bits
398 MOVSX(64, 32, ADDROFFS_REG_0, R(RAX));
392 399
393 // Clear low 32 bits of previous address register 400 // Multiply by 16 to be used as an offset later
394 MOV(32, R(RBX), R(ADDROFFS_REG)); 401 SHL(64, R(ADDROFFS_REG_0), Imm8(4));
395 XOR(64, R(ADDROFFS_REG), R(RBX));
396
397 // Clear high 32-bits of new address register
398 MOV(32, R(RAX), R(RAX));
399 } else if (swiz.DestComponentEnabled(1)) { 402 } else if (swiz.DestComponentEnabled(1)) {
400 // Preserve X-component 403 // Move and sign-extend high 32 bits
401 404 SHR(64, R(RAX), Imm8(32));
402 // Clear high 32-bits of previous address register 405 MOVSX(64, 32, ADDROFFS_REG_1, R(RAX));
403 MOV(32, R(ADDROFFS_REG), R(ADDROFFS_REG));
404 406
405 // Clear low 32 bits of new address register 407 // Multiply by 16 to be used as an offset later
406 MOV(32, R(RBX), R(RAX)); 408 SHL(64, R(ADDROFFS_REG_1), Imm8(4));
407 XOR(64, R(RAX), R(RBX));
408 } 409 }
409
410 OR(64, R(ADDROFFS_REG), R(RAX)); // Combine result
411 } 410 }
412} 411}
413 412