diff options
| author | 2015-07-31 12:40:09 -0400 | |
|---|---|---|
| committer | 2015-08-15 18:01:22 -0400 | |
| commit | cfb354f11f55b940a2f4476f2b42c6813feb3f38 (patch) | |
| tree | b98090f91109d4061e611c72ab28834c992ff08e /src | |
| parent | Shader: Initial implementation of x86_x64 JIT compiler for Pica vertex shaders. (diff) | |
| download | yuzu-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.cpp | 51 |
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 |
| 94 | static const X64Reg UNIFORMS = R10; | 94 | static 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 |
| 96 | static const X64Reg ADDROFFS_REG = R11; | 96 | static const X64Reg ADDROFFS_REG_0 = R10; |
| 97 | static const X64Reg ADDROFFS_REG_1 = R11; | ||
| 97 | /// VS loop count register | 98 | /// VS loop count register |
| 98 | static const X64Reg LOOPCOUNT_REG = R12; | 99 | static 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 | ||