Skip to content

Commit

Permalink
(#354) CodeGen: implement the wide architecture set
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Dec 11, 2022
1 parent 2e82feb commit f556c45
Show file tree
Hide file tree
Showing 14 changed files with 282 additions and 7 deletions.
17 changes: 17 additions & 0 deletions Cesium.CodeGen.Tests/ArchitectureDependentCodeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ private static Task DoTest(TargetArchitectureSet arch, string source)
[InlineData(TargetArchitectureSet.Bit64)]
[InlineData(TargetArchitectureSet.Bit32)]
[InlineData(TargetArchitectureSet.Dynamic)]
[InlineData(TargetArchitectureSet.Wide)]
public Task StaticArray(TargetArchitectureSet arch) => DoTest(arch, """
int main(void)
{
Expand All @@ -29,6 +30,7 @@ int main(void)
[InlineData(TargetArchitectureSet.Bit64)]
[InlineData(TargetArchitectureSet.Bit32)]
[InlineData(TargetArchitectureSet.Dynamic)]
[InlineData(TargetArchitectureSet.Wide)]
public Task StructArray(TargetArchitectureSet arch) => DoTest(arch, """
typedef struct { char *ptr; } foo;
Expand All @@ -43,6 +45,7 @@ int main(void)
// TODO[#355]: [InlineData(TargetArchitectureSet.Bit64)]
// TODO[#355]: [InlineData(TargetArchitectureSet.Bit32)]
[InlineData(TargetArchitectureSet.Dynamic)]
// TODO[#355] [InlineData(TargetArchitectureSet.Wide)]
public Task TwoMemberStructArray(TargetArchitectureSet arch) => DoTest(arch, """
typedef struct { char *ptr; int len; } foo;
Expand All @@ -51,5 +54,19 @@ int main(void)
foo x[3];
return 0;
}
""");

[Theory]
[InlineData(TargetArchitectureSet.Dynamic)]
[InlineData(TargetArchitectureSet.Bit64)]
[InlineData(TargetArchitectureSet.Bit32)]
[InlineData(TargetArchitectureSet.Wide)]
public Task PointerArrayMemberAssign(TargetArchitectureSet arch) => DoTest(arch, """
int main(void)
{
void *x[3];
x[2] = 0;
x[0] = x[2];
}
""");
}
1 change: 1 addition & 0 deletions Cesium.CodeGen.Tests/ArchitectureDependentTypeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ private static Task DoTest(TargetArchitectureSet arch, string source, string @na
[Theory]
[InlineData(TargetArchitectureSet.Bit64)]
[InlineData(TargetArchitectureSet.Bit32)]
[InlineData(TargetArchitectureSet.Wide)]
public Task StructWithPointer(TargetArchitectureSet arch) => DoTest(arch, """
typedef struct
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
System.Int32 <Module>::main()
Locals:
System.Void* V_0
IL_0000: ldc.i4.s 12
IL_0002: conv.u
IL_0003: localloc
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: conv.u
IL_0008: ldc.i4.4
IL_0009: ldc.i4.2
IL_000a: mul
IL_000b: conv.i
IL_000c: add
IL_000d: ldc.i4.0
IL_000e: stind.i
IL_000f: ldloc.0
IL_0010: conv.u
IL_0011: ldc.i4.4
IL_0012: ldc.i4.0
IL_0013: mul
IL_0014: conv.i
IL_0015: add
IL_0016: ldloc.0
IL_0017: conv.u
IL_0018: ldc.i4.4
IL_0019: ldc.i4.2
IL_001a: mul
IL_001b: conv.i
IL_001c: add
IL_001d: ldind.i
IL_001e: stind.i
IL_001f: ldc.i4.0
IL_0020: ret

System.Int32 <Module>::<SyntheticEntrypoint>()
Locals:
System.Int32 V_0
IL_0000: call System.Int32 <Module>::main()
IL_0005: stloc.s V_0
IL_0007: ldloc.s V_0
IL_0009: call System.Void Cesium.Runtime.RuntimeHelpers::Exit(System.Int32)
IL_000e: ldloc.s V_0
IL_0010: ret
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
System.Int32 <Module>::main()
Locals:
System.Void* V_0
IL_0000: ldc.i4.s 24
IL_0002: conv.u
IL_0003: localloc
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: conv.u
IL_0008: ldc.i4.8
IL_0009: ldc.i4.2
IL_000a: mul
IL_000b: conv.i
IL_000c: add
IL_000d: ldc.i4.0
IL_000e: stind.i
IL_000f: ldloc.0
IL_0010: conv.u
IL_0011: ldc.i4.8
IL_0012: ldc.i4.0
IL_0013: mul
IL_0014: conv.i
IL_0015: add
IL_0016: ldloc.0
IL_0017: conv.u
IL_0018: ldc.i4.8
IL_0019: ldc.i4.2
IL_001a: mul
IL_001b: conv.i
IL_001c: add
IL_001d: ldind.i
IL_001e: stind.i
IL_001f: ldc.i4.0
IL_0020: ret

System.Int32 <Module>::<SyntheticEntrypoint>()
Locals:
System.Int32 V_0
IL_0000: call System.Int32 <Module>::main()
IL_0005: stloc.s V_0
IL_0007: ldloc.s V_0
IL_0009: call System.Void Cesium.Runtime.RuntimeHelpers::Exit(System.Int32)
IL_000e: ldloc.s V_0
IL_0010: ret
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
System.Int32 <Module>::main()
Locals:
System.Void* V_0
IL_0000: sizeof System.Void*
IL_0006: ldc.i4.3
IL_0007: mul
IL_0008: conv.u
IL_0009: localloc
IL_000b: stloc.0
IL_000c: ldloc.0
IL_000d: conv.u
IL_000e: sizeof System.Void*
IL_0014: ldc.i4.2
IL_0015: mul
IL_0016: conv.i
IL_0017: add
IL_0018: ldc.i4.0
IL_0019: stind.i
IL_001a: ldloc.0
IL_001b: conv.u
IL_001c: sizeof System.Void*
IL_0022: ldc.i4.0
IL_0023: mul
IL_0024: conv.i
IL_0025: add
IL_0026: ldloc.0
IL_0027: conv.u
IL_0028: sizeof System.Void*
IL_002e: ldc.i4.2
IL_002f: mul
IL_0030: conv.i
IL_0031: add
IL_0032: ldind.i
IL_0033: stind.i
IL_0034: ldc.i4.0
IL_0035: ret

System.Int32 <Module>::<SyntheticEntrypoint>()
Locals:
System.Int32 V_0
IL_0000: call System.Int32 <Module>::main()
IL_0005: stloc.s V_0
IL_0007: ldloc.s V_0
IL_0009: call System.Void Cesium.Runtime.RuntimeHelpers::Exit(System.Int32)
IL_000e: ldloc.s V_0
IL_0010: ret
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
System.Int32 <Module>::main()
Locals:
System.Void* V_0
IL_0000: ldc.i4.s 24
IL_0002: conv.u
IL_0003: localloc
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: conv.u
IL_0008: ldc.i4.8
IL_0009: ldc.i4.2
IL_000a: mul
IL_000b: conv.i
IL_000c: add
IL_000d: ldc.i4.0
IL_000e: stind.i
IL_000f: ldloc.0
IL_0010: conv.u
IL_0011: ldc.i4.8
IL_0012: ldc.i4.0
IL_0013: mul
IL_0014: conv.i
IL_0015: add
IL_0016: ldloc.0
IL_0017: conv.u
IL_0018: ldc.i4.8
IL_0019: ldc.i4.2
IL_001a: mul
IL_001b: conv.i
IL_001c: add
IL_001d: ldind.i
IL_001e: stind.i
IL_001f: ldc.i4.0
IL_0020: ret

System.Int32 <Module>::<SyntheticEntrypoint>()
Locals:
System.Int32 V_0
IL_0000: call System.Int32 <Module>::main()
IL_0005: stloc.s V_0
IL_0007: ldloc.s V_0
IL_0009: call System.Void Cesium.Runtime.RuntimeHelpers::Exit(System.Int32)
IL_000e: ldloc.s V_0
IL_0010: ret
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
System.Int32 <Module>::main()
Locals:
System.Int32* V_0
IL_0000: ldc.i4 2400
IL_0005: conv.u
IL_0006: localloc
IL_0008: stloc.0
IL_0009: ldloc.0
IL_000a: conv.u
IL_000b: ldc.i4.8
IL_000c: ldc.i4 299
IL_0011: mul
IL_0012: conv.i
IL_0013: add
IL_0014: ldc.i4.0
IL_0015: stind.i
IL_0016: ldloc.0
IL_0017: conv.u
IL_0018: ldc.i4.8
IL_0019: ldc.i4 299
IL_001e: mul
IL_001f: conv.i
IL_0020: add
IL_0021: ldind.i
IL_0022: ret

System.Int32 <Module>::<SyntheticEntrypoint>()
Locals:
System.Int32 V_0
IL_0000: call System.Int32 <Module>::main()
IL_0005: stloc.s V_0
IL_0007: ldloc.s V_0
IL_0009: call System.Void Cesium.Runtime.RuntimeHelpers::Exit(System.Int32)
IL_000e: ldloc.s V_0
IL_0010: ret
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
System.Int32 <Module>::main()
Locals:
foo* V_0
IL_0000: ldc.i4.s 24
IL_0002: conv.u
IL_0003: localloc
IL_0005: stloc.0
IL_0006: ldc.i4.0
IL_0007: ret

System.Int32 <Module>::<SyntheticEntrypoint>()
Locals:
System.Int32 V_0
IL_0000: call System.Int32 <Module>::main()
IL_0005: stloc.s V_0
IL_0007: ldloc.s V_0
IL_0009: call System.Void Cesium.Runtime.RuntimeHelpers::Exit(System.Int32)
IL_000e: ldloc.s V_0
IL_0010: ret
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Module: Primary
Type: <Module>

Type: foo
Nested types:
Type: foo/<SyntheticBuffer>x
Pack: 0
Size: 8
Custom attributes:
- CompilerGeneratedAttribute()
- UnsafeValueTypeAttribute()

Fields:
System.Byte* foo/<SyntheticBuffer>x::FixedElementField
Fields:
foo/<SyntheticBuffer>x foo::x
Custom attributes:
- FixedBufferAttribute(System.Byte*, 8)

5 changes: 3 additions & 2 deletions Cesium.CodeGen/Ir/Types/PointerType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

namespace Cesium.CodeGen.Ir.Types;

internal record PointerType(IType Base) : IType
internal sealed record PointerType(IType Base) : IType
{
public virtual TypeReference Resolve(TranslationUnitContext context)
public TypeReference Resolve(TranslationUnitContext context)
{
if (Base is FunctionType ft)
return ft.ResolvePointer(context);
Expand All @@ -22,6 +22,7 @@ public virtual TypeReference Resolve(TranslationUnitContext context)
TargetArchitectureSet.Dynamic => null,
TargetArchitectureSet.Bit32 => 4,
TargetArchitectureSet.Bit64 => 8,
TargetArchitectureSet.Wide => 8,
_ => throw new AssertException($"Unknown architecture set: {arch}.")
};

Expand Down
1 change: 1 addition & 0 deletions Cesium.CodeGen/Ir/Types/StructType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public TypeDefinition Emit(string name, TranslationUnitContext context)
// TODO[#355]: enable explicit layout.
break;
case TargetArchitectureSet.Bit64:
case TargetArchitectureSet.Wide:
structType.PackingSize = 8;
// TODO[#355]: enable explicit layout.
break;
Expand Down
5 changes: 4 additions & 1 deletion Cesium.CodeGen/TargetArchitectureSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ public enum TargetArchitectureSet
Bit32,

/// <summary>An architecture with 64-bit pointers. Targets ARM64 and x86-64 CPUs.</summary>
Bit64
Bit64,

/// <summary>An architecture with 64-bit pointers (even on 32-bit runtime). Targets any CPUs.</summary>
Wide
}
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ $ mono ./out.exe # run with Mono
- `NetStandard` for .NET Standard
- `Net` for .NET 5+
- `--arch <architecture-set>`: specifies the [target architecture set][docs.architecture-sets], defaults to `Dynamic`. Possible values are:
- `Dynamic` (machine-independent),
- `Bit32` (for 32-bit CPUs),
- `Bit64` (for 64-bit CPUs).
- `Dynamic` (machine-independent, calculates pointer size and structure layout in runtime),
- `Bit32` (for 32-bit architectures),
- `Bit64` (for 64-bit architectures),
- `Wide` (machine-independent, uses 64-bit pointers even on 32-bit architectures).
- `--modulekind <moduleKind>`: specifies the output module kind; by default, it is autodetected from the output file extension
- `Dll`: gets detected from a `.dll` extension
- `Console`: gets detected from an `.exe` extension
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture-sets.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ Cesium aims to support the following architecture sets:
Not every C construct allows to use dynamically-calculated size (in particular, it's impossible for pointer-dependent arrays embedded into structures), so this architecture doesn't support all the C standard. It still should be practical for many applications.

**This architecture is machine-independent** and results in producing of an Any CPU-targeting assembly.
- **Wide** architecture **is not implemented, yet** (see issue #354), and uses the fixed pointer size of 64 bits on all computers. This allows it to cover all the features of the C standard, for the cost of some redundancy on 32-bit architectures, and slightly different method signatures for .NET interop.
- **Wide** architecture uses the fixed pointer size of 64 bits on all computers. This allows it to cover all the features of the C standard, for the cost of some redundancy on 32-bit architectures, and slightly different method signatures for .NET interop.

**This architecture is machine-independent** and results in producing of an Any CPU-targeting assembly.

0 comments on commit f556c45

Please sign in to comment.