repos / gbc

GBC - Go B Compiler
git clone https://github.com/xplshn/gbc.git

commit
87ad01e
parent
f5d87de
author
xplshn
date
2025-09-10 22:12:55 +0000 UTC
try to fix floats in LLVM backend

Signed-off-by: xplshn <[email protected]>
1 files changed,  +38, -8
M pkg/codegen/llvm_backend.go
+38, -8
 1@@ -73,7 +73,7 @@ func (b *llvmBackend) compileLLVMIR(llvmIR string) (string, error) {
 2 	asmFile.Close()
 3 	defer os.Remove(asmFile.Name())
 4 
 5-	cmd := exec.Command("llc", "-O3", "-o", asmFile.Name(), llFile.Name())
 6+	cmd := exec.Command("llc", "-O2", "-o", asmFile.Name(), llFile.Name())
 7 	if output, err := cmd.CombinedOutput(); err != nil {
 8 		return "", fmt.Errorf("llc command failed: %w\n--- LLVM IR ---\n%s\n--- Output ---\n%s", err, llvmIR, string(output))
 9 	}
10@@ -814,21 +814,51 @@ func (b *llvmBackend) genCall(instr *ir.Instruction) {
11 	var argParts []string
12 	for i, arg := range instr.Args[1:] {
13 		targetType := b.wordType
14+
15+		// Determine the source type of the argument
16+		sourceType := b.getType(arg)
17+		if fc, ok := arg.(*ir.FloatConst); ok {
18+			sourceType = b.formatType(fc.Typ)
19+		}
20+
21 		if instr.ArgTypes != nil && i < len(instr.ArgTypes) {
22 			requestedType := b.formatType(instr.ArgTypes[i])
23 
24-			// For external functions, let the linker handle type conversions
25-			// Only do integer promotions for small integer types, preserve pointers and floats
26-			if isExternalFunc && (requestedType == "i8" || requestedType == "i16") {
27-				targetType = b.wordType
28+			// - float -> double
29+			// - small integers (i8, i16) -> word type (int promotion)
30+			// - preserve pointers and larger types
31+			if isExternalFunc {
32+				if requestedType == "float" {
33+					targetType = "double"
34+				} else if requestedType == "i8" || requestedType == "i16" {
35+					targetType = b.wordType
36+				} else {
37+					targetType = requestedType
38+				}
39 			} else {
40 				targetType = requestedType
41 			}
42-		} else if g, ok := arg.(*ir.Global); ok {
43-			if _, isString := b.prog.IsStringLabel(g.Name); isString {
44-				targetType = "i8*"
45+		} else {
46+			// No explicit ArgTypes, infer from the argument and apply C standard promotions for external functions
47+			if isExternalFunc {
48+				if sourceType == "float" {
49+					targetType = "double"
50+				} else if sourceType == "i8" || sourceType == "i16" {
51+					targetType = b.wordType
52+				} else if sourceType != "unknown" {
53+					targetType = sourceType
54+				} else if g, ok := arg.(*ir.Global); ok {
55+					if _, isString := b.prog.IsStringLabel(g.Name); isString {
56+						targetType = "i8*"
57+					}
58+				}
59+			} else if g, ok := arg.(*ir.Global); ok {
60+				if _, isString := b.prog.IsStringLabel(g.Name); isString {
61+					targetType = "i8*"
62+				}
63 			}
64 		}
65+
66 		valStr := b.prepareArg(arg, targetType)
67 		argParts = append(argParts, fmt.Sprintf("%s %s", targetType, valStr))
68 	}