Skip to content

Commit

Permalink
Add more clang intrinsics
Browse files Browse the repository at this point in the history
  • Loading branch information
praeclarum committed Sep 2, 2022
1 parent 968d759 commit 6c474bb
Show file tree
Hide file tree
Showing 5 changed files with 306 additions and 175 deletions.
48 changes: 44 additions & 4 deletions Iril/Compilation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,26 @@ public class Compilation
public MethodReference sysMathFloorD;
public MethodReference sysMathSqrtD;
public MethodReference sysMathPowD;
public MethodReference sysMathMinSByte;
public MethodReference sysMathMinInt16;
public MethodReference sysMathMinInt32;
public MethodReference sysMathMinInt64;
public MethodReference sysMathMinByte;
public MethodReference sysMathMinUInt16;
public MethodReference sysMathMinUInt32;
public MethodReference sysMathMinUInt64;
public MethodReference sysMathMinS;
public MethodReference sysMathMinD;
public MethodReference sysMathMaxSByte;
public MethodReference sysMathMaxInt16;
public MethodReference sysMathMaxInt32;
public MethodReference sysMathMaxInt64;
public MethodReference sysMathMaxByte;
public MethodReference sysMathMaxUInt16;
public MethodReference sysMathMaxUInt32;
public MethodReference sysMathMaxUInt64;
public MethodReference sysMathMaxS;
public MethodReference sysMathMaxD;
public MethodReference sysSingleIsNaN;
public MethodReference sysDoubleIsNaN;
TypeReference sysEventArgs;
Expand Down Expand Up @@ -191,7 +211,8 @@ public MethodDefinition GetSystemMethod (Symbol symbol)
f.ReferenceCount++;
return f.ILDefinition;
}
throw new KeyNotFoundException ($"Failed to find system method `{symbol}`");
var methods = String.Join(", ", externalMethodDefs.Select(x => x.Key));
throw new KeyNotFoundException ($"Failed to find system method `{symbol}` ({symbol.GetType()}): {methods}");
}

readonly Lazy<TypeDefinition> dataType;
Expand Down Expand Up @@ -360,6 +381,26 @@ void FindSystemTypes ()
sysMathFloorD = ImportMethod (sysMath, sysDouble, "Floor", sysDouble);
sysMathSqrtD = ImportMethod (sysMath, sysDouble, "Sqrt", sysDouble);
sysMathPowD = ImportMethod (sysMath, sysDouble, "Pow", sysDouble, sysDouble);
sysMathMaxSByte = ImportMethod (sysMath, sysSByte, "Max", sysSByte, sysSByte);
sysMathMaxInt16 = ImportMethod (sysMath, sysInt16, "Max", sysInt16, sysInt16);
sysMathMaxInt32 = ImportMethod (sysMath, sysInt32, "Max", sysInt32, sysInt32);
sysMathMaxInt64 = ImportMethod (sysMath, sysInt64, "Max", sysInt64, sysInt64);
sysMathMaxByte = ImportMethod (sysMath, sysByte, "Max", sysByte, sysByte);
sysMathMaxUInt16 = ImportMethod (sysMath, sysUInt16, "Max", sysUInt16, sysUInt16);
sysMathMaxUInt32 = ImportMethod (sysMath, sysUInt32, "Max", sysUInt32, sysUInt32);
sysMathMaxUInt64 = ImportMethod (sysMath, sysUInt64, "Max", sysUInt64, sysUInt64);
sysMathMaxS = ImportMethod (sysMath, sysSingle, "Max", sysSingle, sysSingle);
sysMathMaxD = ImportMethod (sysMath, sysDouble, "Max", sysDouble, sysDouble);
sysMathMinSByte = ImportMethod (sysMath, sysSByte, "Min", sysSByte, sysSByte);
sysMathMinInt16 = ImportMethod (sysMath, sysInt16, "Min", sysInt16, sysInt16);
sysMathMinInt32 = ImportMethod (sysMath, sysInt32, "Min", sysInt32, sysInt32);
sysMathMinInt64 = ImportMethod (sysMath, sysInt64, "Min", sysInt64, sysInt64);
sysMathMinByte = ImportMethod (sysMath, sysByte, "Min", sysByte, sysByte);
sysMathMinUInt16 = ImportMethod (sysMath, sysUInt16, "Min", sysUInt16, sysUInt16);
sysMathMinUInt32 = ImportMethod (sysMath, sysUInt32, "Min", sysUInt32, sysUInt32);
sysMathMinUInt64 = ImportMethod (sysMath, sysUInt64, "Min", sysUInt64, sysUInt64);
sysMathMinS = ImportMethod (sysMath, sysSingle, "Min", sysSingle, sysSingle);
sysMathMinD = ImportMethod (sysMath, sysDouble, "Min", sysDouble, sysDouble);
sysEventArgs = Import ("System.EventArgs");
sysIAsyncResult = Import ("System.IAsyncResult");
sysAsyncCallback = Import ("System.AsyncCallback");
Expand Down Expand Up @@ -1073,23 +1114,22 @@ TypeDefinition ImportType (TypeDefinition type, Action<TypeDefinition> add)
continue;

var symbol = export != null ? Symbol.Intern (export.ConstructorArguments[0].Value.ToString ()) : null;

var (im, imImport) = ImportTypeMethod (m, it, symbol);
if (im == null)
continue;

importMethodBodies.Add (imImport);

if (export != null) {


externalMethodDefs[symbol] = new DefinedFunction {
Symbol = symbol,
IRModule = null,
IRDefinition = null,
ILDefinition = im,
ParamSyms = new SymbolTable<ParameterDefinition> (),
};
// Console.WriteLine($"FOUND EXPORT `{symbol}` ({symbol.GetType()})");
}
else if (im.IsConstructor) {
// OK
Expand Down
140 changes: 97 additions & 43 deletions Iril/FunctionCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,7 @@ void EmitInstruction(LocalSymbol assignedSymbol, IR.Instruction instruction, IR.
//if (cbr.IfFalse.Symbol != nextBlock?.Symbol)
var falseDest = GetLabel (cbr.IfFalse, block, context);
if (context.IsExceptionHandler && !context.IsProtecting (cbr.IfFalse)) {
Console.WriteLine ("EMIT FARLSE");
// Console.WriteLine ("EMIT FALSE");
Emit (il.Create (OpCodes.Leave, falseDest));
}
else {
Expand Down Expand Up @@ -2450,9 +2450,15 @@ void EmitCall(IR.CallInstruction call, Block fromBlock)
{
if (call.Pointer is IR.GlobalValue gv) {
switch (gv.Symbol.Text) {
case "@llvm.lifetime.start.p0i8":
case "@llvm.lifetime.end.p0i8":
case "@llvm.ceil.f64":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathCeilD));
return;
case "@llvm.ceil.v2f64" when call.Arguments[0].Type is VectorType ceilVt:
EmitVectorFunc (call.Arguments[0].Value, ceilVt, compilation.sysMathCeilD);
return;
case "@llvm.dbg.declare":
case "@llvm.dbg.label":
return;
case "@llvm.dbg.value":
// call void @llvm.dbg.value(metadata %struct._parser_t* %3, metadata !1020, metadata !DIExpression(DW_OP_deref)), !dbg !1140
Expand All @@ -2473,25 +2479,18 @@ void EmitCall(IR.CallInstruction call, Block fromBlock)
}
}
return;
case "@llvm.ceil.f64":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathCeilD));
return;
case "@llvm.ceil.v2f64" when call.Arguments[0].Type is VectorType ceilVt:
EmitVectorFunc (call.Arguments[0].Value, ceilVt, compilation.sysMathCeilD);
return;
case "@llvm.fabs.f64":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathAbsD));
return;
case "@llvm.sqrt.f64":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathSqrtD));
return;
case "@llvm.pow.f64":
case "@llvm.fshl.i64":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathPowD));
EmitValue (call.Arguments[2].Value, call.Arguments[2].Type);
Emit (il.Create (OpCodes.Call, compilation.GetSystemMethod (gv.Symbol)));
return;
case "@llvm.lifetime.start.p0i8":
case "@llvm.lifetime.end.p0i8":
return;
case "@llvm.objectsize.i32.p0i8" when call.Arguments.Length >= 3: {
var min = 0;
Expand Down Expand Up @@ -2519,6 +2518,31 @@ void EmitCall(IR.CallInstruction call, Block fromBlock)
}
}
return;
// declare void @llvm.memcpy.p0i8.p0i8.i32(i8* <dest>, i8* <src>,
// i32 <len>, i1 <isvolatile>)
case "@llvm.memcpy.p0i8.p0i8.i32" when call.Arguments.Length >= 3:
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
EmitValue (call.Arguments[2].Value, call.Arguments[2].Type);
Emit (il.Create (OpCodes.Cpblk));
return;
// declare void @llvm.memcpy.p0i8.p0i8.i64(i8* <dest>, i8* <src>,
// i64 <len>, i1 <isvolatile>)
case "@llvm.memcpy.p0i8.p0i8.i64" when call.Arguments.Length >= 3:
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
EmitValue (call.Arguments[2].Value, call.Arguments[2].Type);
Emit (il.Create (OpCodes.Conv_U4));
Emit (il.Create (OpCodes.Cpblk));
return;
// declare void @llvm.memmove.p0i8.p0i8.i64(i8* <dest>, i8* <src>,
// i64 <len>, i1 <isvolatile>)
case "@llvm.memmove.p0i8.p0i8.i64" when call.Arguments.Length >= 3:
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
EmitValue (call.Arguments[2].Value, call.Arguments[2].Type);
Emit (il.Create (OpCodes.Call, compilation.GetSystemMethod (gv.Symbol)));
return;
// declare void @llvm.memset.p0i8.i32(i8* <dest>, i8 <val>,
// i32<len>, i1<isvolatile>)
case "@llvm.memset.p0i8.i32" when call.Arguments.Length >= 3:
Expand All @@ -2536,39 +2560,74 @@ void EmitCall(IR.CallInstruction call, Block fromBlock)
Emit (il.Create (OpCodes.Conv_U4));
Emit (il.Create (OpCodes.Initblk));
return;
// declare void @llvm.memcpy.p0i8.p0i8.i32(i8* <dest>, i8* <src>,
// i32 <len>, i1 <isvolatile>)
case "@llvm.memcpy.p0i8.p0i8.i32" when call.Arguments.Length >= 3:
case "@llvm.pow.f64":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
EmitValue (call.Arguments[2].Value, call.Arguments[2].Type);
Emit (il.Create (OpCodes.Cpblk));
Emit (il.Create (OpCodes.Call, compilation.sysMathPowD));
return;
// declare void @llvm.memcpy.p0i8.p0i8.i64(i8* <dest>, i8* <src>,
// i64 <len>, i1 <isvolatile>)
case "@llvm.memcpy.p0i8.p0i8.i64" when call.Arguments.Length >= 3:
case "@llvm.smax.i8":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
EmitValue (call.Arguments[2].Value, call.Arguments[2].Type);
Emit (il.Create (OpCodes.Conv_U4));
Emit (il.Create (OpCodes.Cpblk));
Emit (il.Create (OpCodes.Call, compilation.sysMathMaxSByte));
return;
case "@llvm.smax.i16":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathMaxInt16));
return;
case "@llvm.smax.i32":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathMaxInt32));
return;
case "@llvm.smax.i64":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathMaxInt64));
return;
case "@llvm.sqrt.f64":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathSqrtD));
return;
case "@llvm.stackrestore":
compilation.WarningMessage (module.SourceFilename, $"Stack restore is not supported in `{MangledName.Demangle (function.Symbol)}`");
return;
// declare void @llvm.memmove.p0i8.p0i8.i64(i8* <dest>, i8* <src>,
// i64 <len>, i1 <isvolatile>)
//case "@llvm.memmove.p0i8.p0i8.i64" when call.Arguments.Length >= 3:
// EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
// EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
// EmitValue (call.Arguments[2].Value, call.Arguments[2].Type);
// Emit (il.Create (OpCodes.Conv_U4));
// Emit (il.Create (OpCodes.Cpblk));
// return;
case "@llvm.stacksave":
compilation.WarningMessage (module.SourceFilename, $"Stack save is not supported in `{MangledName.Demangle (function.Symbol)}`");
Emit (il.Create (OpCodes.Ldc_I4_0));
Emit (il.Create (OpCodes.Conv_U));
return;
case "@llvm.stackrestore":
compilation.WarningMessage (module.SourceFilename, $"Stack restore is not supported in `{MangledName.Demangle (function.Symbol)}`");
case "@llvm.trap":
Emit (il.Create (OpCodes.Ldstr, "Trap"));
Emit (il.Create (OpCodes.Newobj, compilation.sysExceptionCtor));
Emit (il.Create (OpCodes.Throw));
return;
case "@llvm.umax.i8":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathMaxByte));
return;
case "@llvm.umax.i16":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathMaxUInt16));
return;
case "@llvm.umax.i32":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathMaxUInt32));
return;
case "@llvm.umax.i64":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
Emit (il.Create (OpCodes.Call, compilation.sysMathMaxUInt64));
return;
case "@llvm.usub.sat.i64":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
EmitValue (call.Arguments[1].Value, call.Arguments[1].Type);
Emit (il.Create (OpCodes.Sub));
Emit (il.Create (OpCodes.Ldc_I8, 0L));
Emit (il.Create (OpCodes.Call, compilation.sysMathMaxInt64));
return;
case "@llvm.va_start":
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
Expand All @@ -2579,11 +2638,6 @@ void EmitCall(IR.CallInstruction call, Block fromBlock)
EmitValue (call.Arguments[0].Value, call.Arguments[0].Type);
Emit (il.Create (OpCodes.Call, compilation.GetSystemMethod (gv.Symbol)));
return;
case "@llvm.trap":
Emit (il.Create (OpCodes.Ldstr, "Trap"));
Emit (il.Create (OpCodes.Newobj, compilation.sysExceptionCtor));
Emit (il.Create (OpCodes.Throw));
return;
default:
if (compilation.TryGetFunction (module, gv.Symbol, out var m)) {

Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@

all: Iril/IR/Parser.cs


Iril/IR/Parser.cs: Iril/IR/IR.jay Makefile Lib/skeleton.cs.template
./Lib/jay -c -v Iril/IR/IR.jay < Lib/skeleton.cs.template > $@

clean:
rm -rf Iril/bin Iril/obj Cli/bin Cli/obj

restore:
dotnet restore
35 changes: 35 additions & 0 deletions StdLib/Llvm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,40 @@ public unsafe static void va_end (byte* arglist)
Memory.UnregisterMemory (list->reg_save_area);
}
}

[DllExport ("@llvm.fshl.i64")]
public unsafe static ulong fshl_i64(ulong a, ulong b, ulong c)
{
// Performs a funnel shift left:
// The first two values are concatenated as { %a : %b }
// (%a is the most significant bits of the wide value),
// the combined value is shifted left,
// and the most significant bits are extracted
// to produce a result that is the same size as the original arguments.
var result = a;
while (c > 0) {
result = (result << 1) | (b >> 63);
b <<= 1;
c--;
}
return result;
}

[DllExport ("@llvm.memmove.p0i8.p0i8.i64")]
public unsafe static void memmove (byte* dest, byte* src, size_t len)
{
byte* d = (byte*)dest;
byte* s = (byte*)src;
byte* r = d;
if (s < d) {
d += len;
s += len;
while (len-- != 0)
*--d = *--s;
}
else
while (len-- != 0)
*d++ = *s++;
}
}
}
Loading

0 comments on commit 6c474bb

Please sign in to comment.