1
votes

I am learning the HLSL language and have an assembly code that I try to reverse:

mul r0.x, cb0[11].z, cb1[69].w
frc r0.x, r0.x
add r0.y, r0.x, l(0.500000)
frc r0.y, r0.y
add r0.z, r0.y, l(0.250000)
frc r0.z, r0.z
add r0.w, r0.z, l(0.500000)
frc r0.w, r0.w
mul r1.x, r0.w, l(6.283185)
sincos null, r1.x, r1.x

And here is what I wrote when I tried to reverse the assembly code:

float3 ps_main( const PixelInput pixel ) : SV_TARGET
{
    float4 Scroll;
    Scroll.x = frac(colorScroll.z * gameTime.w);
    Scroll.y = frac( Scroll.x + 0.5f);
    Scroll.z = frac( Scroll.y + 0.25f);
    Scroll.w = frac( Scroll.z + 0.5f);

    float3 ScollSpeed =  Scroll.w * 6.283185f;

    return ScollSpeed;
}

But when compiling this, the following assembly code is generated:

dcl_temps 1
mul r0.x, cb0[11].z, cb1[69].w
frc r0.x, r0.x
add r0.x, r0.x, l(0.500000)
frc r0.x, r0.x
add r0.x, r0.x, l(0.250000)
frc r0.x, r0.x
add r0.x, r0.x, l(0.500000)
frc r0.x, r0.x
mul o0.xyz, r0.xxxx, l(6.283185, 6.283185, 6.283185, 0.000000)
ret 

Why are all my variables r0.x? I want that Scroll.y is r0.y like in the original assembly.

1
I am not familiar with HLSL, but it is possible that the compiler is optimizing(since you derive Scroll.y and Scroll.z from Scroll.x during variable declaration)?inverzeio

1 Answers

0
votes

The compiler is optimizing your code to optimize register usage, since you only use the w component at the end, xyz can be packed into a single scalar:

float3 ScollSpeed =  Scroll.w * 6.283185f;

it detects that ScollSpeed.xyz are not needed, and can be packed in a single float (the following code would be equivalent) :

float3 PS(  ) : SV_TARGET
{
    float Scroll;
    Scroll = frac(colorScroll.z * gameTime.w);
    Scroll = frac( Scroll + 0.5f);
    Scroll = frac( Scroll + 0.25f);
    Scroll = frac( Scroll + 0.5f);

    float3 ScollSpeed =  Scroll * 6.283185f;

    return ScollSpeed;
}

it then only needs the first register component to perform the whole operation (hence why you only have r0.x)