Skip to content

Instantly share code, notes, and snippets.

@kunalspathak
Last active September 24, 2024 16:57
Show Gist options
  • Save kunalspathak/b03d740762993482c692dcf7c51d5fa1 to your computer and use it in GitHub Desktop.
Save kunalspathak/b03d740762993482c692dcf7c51d5fa1 to your computer and use it in GitHub Desktop.
FFR ABI examples
// save/restore FFR because liveness crosses call boundaries
public Vector<long> Test(Vector<long> mask)
{
  Sve.SetFfr(mask);
  return Sve.GetFfrInt64();
}

/*
    ptrue   p0.d
    cmpne   p14.d, p0/z, z0.d, #0
    wrffr   p14.b
    rdffr   p0.b
    mov     z0.d, p0/z, #1
*/
public Vector<long> Test(Vector<long> mask)
{
  Sve.SetFfr(mask);
  Foo();
  return Sve.GetFfrInt64();
}

/*
    ptrue   p0.d
    cmpne   p0.d, p0/z, z0.d, #0
    wrffr   p0.b
    rdffr   p0.b
    add     xip1, fp, #24
    str     p0, [xip1]
    movz    x0, #0x7B58      // code for simplerepro.SimpleRepro:Foo()
    movk    x0, #0xFBAB LSL #16
    movk    x0, #0x7FF9 LSL #32
    ldr     x0, [x0]
    blr     x0
    add     xip1, fp, #24
    ldr     p0, [xip1]
    mov     z0.d, p0/z, #1 
*/
// No need to save/restore because liveness ends before method call
public Vector<long> Test(Vector<long> mask)
{
  Sve.SetFfr(mask);
  var result = Sve.LoadVectorFirstFaulting(mask, address);
  var maskFfr = Sve.GetFfrInt64();
  Foo(maskFfr);
  return result;
}

/*
    ptrue   p0.d
    cmpne   p0.d, p0/z, z0.d, #0
    wrffr   p0.b
    ldff1d  { z8.d }, p0/z, [x0]
    rdffr   p0.b
    mov     z0.d, p0/z, #1
    movz    x0, #0x62B0      // code for simplerepro.SimpleRepro:Foo(System.Numerics.Vector`1[long])
    movk    x0, #0x425 LSL #16
    movk    x0, #0x7FFD LSL #32
    ldr     x0, [x0]
    mov     v9.d[0], v8.d[1]
    blr     x0
    mov     v8.d[1], v9.d[0]
    mov     v0.16b, v8.16b
*/
// No need to save/restore because liveness ends before method call
public Vector<long> Test(Vector<long> mask)
{
  Sve.SetFfr(mask);
  Foo(mask);
  var result = Sve.LoadVectorFirstFaulting(mask, address);
  Foo(result);
  return Sve.GetFfrInt64();
}

/*
    ptrue   p0.d
    cmpne   p0.d, p0/z, z0.d, #0
    add     xip1, fp, #32
    str     p0, [xip1]
    wrffr   p0.b
    rdffr   p1.b
    add     xip1, fp, #24
    str     p1, [xip1]
    movz    x0, #0x7BB8      // code for simplerepro.SimpleRepro:Foo(System.Numerics.Vector`1[long])
    movk    x0, #0xC279 LSL #16
    movk    x0, #0x7FF9 LSL #32
    ldr     x0, [x0]
    blr     x0
    add     xip1, fp, #32
    ldr     p0, [xip1]
    add     xip1, fp, #24
    ldr     p1, [xip1]
    wrffr   p1.b
    ldff1d  { z0.d }, p0/z, [x19]
    rdffr   p1.b
    add     xip1, fp, #24
    str     p1, [xip1]
    movz    x0, #0x7BB8      // code for simplerepro.SimpleRepro:Foo(System.Numerics.Vector`1[long])
    movk    x0, #0xC279 LSL #16
    movk    x0, #0x7FF9 LSL #32
    ldr     x0, [x0]
    blr     x0
    add     xip1, fp, #24
    ldr     p1, [xip1]
    mov     z0.d, p1/z, #1
*/
// No need to save/restore because liveness ends before method call
public Vector<long> Test(Vector<long> mask)
{
  var r1 = Sve.GetFfrInt64();
  Foo(mask);
  var result = Sve.LoadVectorFirstFaulting(mask, address);
  Foo(result);
  return r1;
}

/*
    add     xip1, fp, #16
    ldr     p0, [xip1]
    mov     z9.d, p0/z, #1
    mov     v0.16b, v8.16b
    movz    x0, #0x7BB8      // code for simplerepro.SimpleRepro:Foo(System.Numerics.Vector`1[long])
    movk    x0, #0xC27B LSL #16
    movk    x0, #0x7FF9 LSL #32
    ldr     x0, [x0]
    mov     v10.d[0], v8.d[1]
    mov     v11.d[0], v9.d[1]
    blr     x0
    ptrue   p0.d
    mov     v8.d[1], v10.d[0]
    cmpne   p0.d, p0/z, z8.d, #0
    add     xip1, fp, #16
    ldr     p1, [xip1]
    wrffr   p1.b
    ldff1d  { z0.d }, p0/z, [x19]
    movz    x0, #0x7BB8      // code for simplerepro.SimpleRepro:Foo(System.Numerics.Vector`1[long])
    movk    x0, #0xC27B LSL #16
    movk    x0, #0x7FF9 LSL #32
    ldr     x0, [x0]
    blr     x0
    mov     v9.d[1], v11.d[0]
    mov     v0.16b, v9.16b
*/
// No need to save/restore because liveness ends before method call
public Vector<long> Test(Vector<long> mask)
{
  var result = Sve.LoadVectorFirstFaulting(mask, address);
  Foo(result);
  return Sve.GetFfrInt64();
}

/*
    ptrue   p0.d
    cmpne   p0.d, p0/z, z0.d, #0
    add     xip1, fp, #24
    ldr     p1, [xip1]
    wrffr   p1.b
    ldff1d  { z0.d }, p0/z, [x0]
    rdffr   p1.b
    add     xip1, fp, #24
    str     p1, [xip1]
    movz    x0, #0x7BD0      // code for simplerepro.SimpleRepro:Foo(System.Numerics.Vector`1[long])
    movk    x0, #0xC279 LSL #16
    movk    x0, #0x7FF9 LSL #32
    ldr     x0, [x0]
    blr     x0
    add     xip1, fp, #24
    ldr     p1, [xip1]
    mov     z0.d, p1/z, #1
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment