Question

I'm making a small language that is very similar to hlsl but supports only pixel shaders. This language uses reflection.emit to build dot net assemblies that implement the same functionality. I'm currently testing my implementation of the branch instruction "if" and in one of my unit tests (a large if with inner if else's) failed with the following error message:

System.NotSupportedException : Illegal one-byte branch at position: 32. Requested branch was: 132.

I've traced the problem to the use of short form instructions in my case OpCodes.Br_S. The solution was simple, I've replaced OpCodes.Br_S with OpCodes.Br however I have a couple of questions about this solution:

This solution has impact on the performance of the generated code ? If i want to correctly generate Br_S for single byte and Br for the other cases how can i do that ? The problem here is that I'm using a visitor pattern and for a branch instruction like the "if" I have to output Br or Br_s first and at that point I have no way of knowing if the remaining code will require more than single byte to jump to the label. To better illustrate my question this is the code that I generate for the following statements:

My Language:

int a = -1; if (1>1) { a=1; } else if(2>2) { a=2; }

IL:

.method public virtual final instance int32 Main() cil managed {

.maxstack 4
.locals init (
    [0] int32 num)
L_0000: ldc.i4.m1 
L_0001: stloc.0 
L_0002: ldc.i4.1 
L_0003: ldc.i4.1 
L_0004: ble.s L_000a
L_0006: ldc.i4.1 
L_0007: stloc.0 
L_0008: br.s L_0010
L_000a: ldc.i4.2 
L_000b: ldc.i4.2 
L_000c: ble.s L_0010
L_000e: ldc.i4.2 
L_000f: stloc.0 
L_0010: ldloc.0 
L_0011: ret 

}

In this case I'm using two short form instructions ble.s and br.s to implement the ifs just like what the .net compiler does. However .NET compiler is able to choose br.s or br according with the cases, my problem is how can i do something similar ?

Tnks

Was it helpful?

Solution

If you want to do this, you'll need to calculate the offset to the branch target before generating the branch itself, and then determine if the offset is small enough to be reached by the short form instruction. I don't think that there's a particularly easy way to do this using the Reflection.Emit library.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top