From 7e00d3d8de8193340b04ea6342a03d26b2e450d3 Mon Sep 17 00:00:00 2001 From: wesuRage Date: Mon, 13 Jan 2025 02:39:08 -0300 Subject: [PATCH 1/3] fix(double): added floating point case --- .../generator/expressions/generate_unary_minus.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/generator/expressions/generate_unary_minus.cpp b/src/backend/generator/expressions/generate_unary_minus.cpp index e97e473..ff83d27 100644 --- a/src/backend/generator/expressions/generate_unary_minus.cpp +++ b/src/backend/generator/expressions/generate_unary_minus.cpp @@ -5,9 +5,9 @@ llvm::Value *generate_unary_minus(UnaryMinusExpr *node, llvm::LLVMContext &Conte // Generate LLVM IR for the operand (the value to apply the unary minus operation on) llvm::Value *Operand = generate_expr(node->op, Context, Builder, Module); - // Create a floating-point negation instruction, which negates the operand (i.e., multiplies it by -1) - llvm::Value *Negated = Builder.CreateNeg(Operand, "negtmp"); - - // Return the result of the negation - return Negated; + if (Operand->getType()->isDoubleTy()) { + return Builder.CreateFNeg(Operand, "negtmp"); + } else { + return Builder.CreateNeg(Operand, "negtmp"); + } } \ No newline at end of file From a3af421f9cff50be0c336ff596226a5afa2823d4 Mon Sep 17 00:00:00 2001 From: wesuRage Date: Mon, 13 Jan 2025 02:39:28 -0300 Subject: [PATCH 2/3] feat(power): added power intrinsics --- .../expressions/generate_binary_expr.cpp | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/backend/generator/expressions/generate_binary_expr.cpp b/src/backend/generator/expressions/generate_binary_expr.cpp index 0bb1fe3..63fed45 100644 --- a/src/backend/generator/expressions/generate_binary_expr.cpp +++ b/src/backend/generator/expressions/generate_binary_expr.cpp @@ -3,7 +3,7 @@ #include "backend/generator/symbols/identifier_symbol_table.hpp" #include "backend/generator/symbols/string_symbol_table.hpp" #include "backend/generator/symbols/function_symbol_table.hpp" -#include +#include llvm::Value *generate_binary_expr(BinaryExprNode *node, llvm::LLVMContext &Context, llvm::IRBuilder &Builder, llvm::Module &Module) { llvm::Value *L = generate_expr(node->left, Context, Builder, Module); @@ -63,8 +63,6 @@ llvm::Value *generate_binary_expr(BinaryExprNode *node, llvm::LLVMContext &Conte return resultBuffer; } } else { - - llvm::errs() << "Value: " << L->getValueName()->getValue()->getName().str() << "\n"; const SymbolInfo* symbolInfo; symbolInfo = find_identifier(static_cast(node->left->data)->symbol); @@ -118,6 +116,18 @@ llvm::Value *generate_binary_expr(BinaryExprNode *node, llvm::LLVMContext &Conte if (strcmp(node->op, "^") == 0) return Builder.CreateXor(L, R, "xortmp"); if (strcmp(node->op, ">>") == 0) return Builder.CreateAShr(L, R, "shrtmp"); if (strcmp(node->op, "<<") == 0) return Builder.CreateShl(L, R, "shltmp"); + if (strcmp(node->op, "**") == 0) { + if (L->getType()->isIntegerTy()) { + L = Builder.CreateSIToFP(L, llvm::Type::getDoubleTy(Context), "cast_to_fp_L"); + } + if (R->getType()->isIntegerTy()) { + R = Builder.CreateSIToFP(R, llvm::Type::getDoubleTy(Context), "cast_to_fp_R"); + } + + llvm::Function *powFunction = llvm::Intrinsic::getDeclaration(&Module, llvm::Intrinsic::pow, { L->getType() }); + return Builder.CreateCall(powFunction, { L, R }, "powtmp"); + } + if (strcmp(node->op, "==") == 0) return Builder.CreateICmpEQ(L, R, "eqtmp"); if (strcmp(node->op, "!=") == 0) return Builder.CreateICmpNE(L, R, "netmp"); @@ -141,6 +151,10 @@ llvm::Value *generate_binary_expr(BinaryExprNode *node, llvm::LLVMContext &Conte if (strcmp(node->op, "-") == 0) return Builder.CreateFSub(L, R, "subtmp"); if (strcmp(node->op, "*") == 0) return Builder.CreateFMul(L, R, "multmp"); if (strcmp(node->op, "/") == 0) return Builder.CreateFDiv(L, R, "divtmp"); + if (strcmp(node->op, "**") == 0) { + llvm::Function *powFunction = llvm::Intrinsic::getDeclaration(&Module, llvm::Intrinsic::pow, { L->getType() }); + return Builder.CreateCall(powFunction, { L, R }, "powtmp"); + } if (strcmp(node->op, "==") == 0) return Builder.CreateFCmpOEQ(L, R, "eqtmp"); if (strcmp(node->op, "!=") == 0) return Builder.CreateFCmpONE(L, R, "netmp"); From f5907f8cffbdacd05bce4587f67b058e1b7ca847 Mon Sep 17 00:00:00 2001 From: wesuRage Date: Mon, 13 Jan 2025 02:40:00 -0300 Subject: [PATCH 3/3] feat(ftos): added float/double to string --- libs/lib.ll | 101 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 42 deletions(-) diff --git a/libs/lib.ll b/libs/lib.ll index 4e7f254..8639fad 100644 --- a/libs/lib.ll +++ b/libs/lib.ll @@ -311,55 +311,54 @@ exit: ; preds = %finalize, %abort declare ptr @malloc(i64) - -define ptr @itos(i32 %num) { +define ptr @itos(i64 %num) { entry: ; Alocação de variáveis %is_negative = alloca i1 - %num_ptr = alloca i32 + %num_ptr = alloca i64 %buffer = alloca ptr - %i = alloca i32 + %i = alloca i64 ; Inicializa variáveis - store i32 %num, ptr %num_ptr + store i64 %num, ptr %num_ptr store i1 0, ptr %is_negative ; Aloca buffer dinâmico para a string (máximo 12 bytes: "-2147483648" + '\0') %buf = call ptr @malloc(i64 12) store ptr %buf, ptr %buffer - store i32 0, ptr %i + store i64 0, ptr %i ; Verifica se o número é negativo - %num_val = load i32, ptr %num_ptr - %is_neg = icmp slt i32 %num_val, 0 + %num_val = load i64, ptr %num_ptr + %is_neg = icmp slt i64 %num_val, 0 br i1 %is_neg, label %negative, label %positive negative: ; Bloco para números negativos store i1 1, ptr %is_negative - %neg_num = sub i32 0, %num_val - store i32 %neg_num, ptr %num_ptr + %neg_num = sub i64 0, %num_val + store i64 %neg_num, ptr %num_ptr br label %extract_digits positive: ; Continua o processamento br label %extract_digits extract_digits: ; Extrai os dígitos - %num_val2 = load i32, ptr %num_ptr - %digit = urem i32 %num_val2, 10 - %char_digit = add i32 %digit, 48 ; Converte para caractere - %i_val = load i32, ptr %i + %num_val2 = load i64, ptr %num_ptr + %digit = urem i64 %num_val2, 10 + %char_digit = add i64 %digit, 48 ; Converte para caractere + %i_val = load i64, ptr %i %buf_ptr = load ptr, ptr %buffer - %str_loc = getelementptr i8, ptr %buf_ptr, i32 %i_val - store i32 %char_digit, ptr %str_loc + %str_loc = getelementptr i8, ptr %buf_ptr, i64 %i_val + store i64 %char_digit, ptr %str_loc ; Atualiza número e índice - %next_num = sdiv i32 %num_val2, 10 - store i32 %next_num, ptr %num_ptr - %next_i = add i32 %i_val, 1 - store i32 %next_i, ptr %i + %next_num = sdiv i64 %num_val2, 10 + store i64 %next_num, ptr %num_ptr + %next_i = add i64 %i_val, 1 + store i64 %next_i, ptr %i ; Verifica se o número é maior que zero - %is_not_zero = icmp ne i32 %next_num, 0 + %is_not_zero = icmp ne i64 %next_num, 0 br i1 %is_not_zero, label %extract_digits, label %check_negative check_negative: ; Adiciona o sinal de menos se necessário @@ -367,39 +366,39 @@ check_negative: ; Adiciona o sinal de menos se necessário br i1 %is_neg2, label %add_minus, label %reverse_buffer add_minus: ; Adiciona o sinal de menos - %i_val2 = load i32, ptr %i + %i_val2 = load i64, ptr %i %buf_ptr2 = load ptr, ptr %buffer - %str_loc2 = getelementptr i8, ptr %buf_ptr2, i32 %i_val2 + %str_loc2 = getelementptr i8, ptr %buf_ptr2, i64 %i_val2 store i8 45, ptr %str_loc2 ; '-' é 45 na tabela ASCII - %next_i2 = add i32 %i_val2, 1 - store i32 %next_i2, ptr %i + %next_i2 = add i64 %i_val2, 1 + store i64 %next_i2, ptr %i br label %reverse_buffer reverse_buffer: ; Reverte o buffer %buf_ptr3 = load ptr, ptr %buffer - %len = load i32, ptr %i + %len = load i64, ptr %i ; Índices para reversão - %start = alloca i32 - %end = alloca i32 - store i32 0, ptr %start - %end_idx = sub i32 %len, 1 - store i32 %end_idx, ptr %end + %start = alloca i64 + %end = alloca i64 + store i64 0, ptr %start + %end_idx = sub i64 %len, 1 + store i64 %end_idx, ptr %end br label %reverse_loop reverse_loop: ; Loop para inverter os caracteres - %start_idx = load i32, ptr %start - %end_idx_initial = load i32, ptr %end - %cmp = icmp slt i32 %start_idx, %end_idx_initial + %start_idx = load i64, ptr %start + %end_idx_initial = load i64, ptr %end + %cmp = icmp slt i64 %start_idx, %end_idx_initial br i1 %cmp, label %swap_chars, label %finalize_string swap_chars: ; Troca os caracteres %buf_ptr4 = load ptr, ptr %buffer ; Posições dos caracteres - %start_char_ptr = getelementptr i8, ptr %buf_ptr4, i32 %start_idx - %end_char_ptr = getelementptr i8, ptr %buf_ptr4, i32 %end_idx + %start_char_ptr = getelementptr i8, ptr %buf_ptr4, i64 %start_idx + %end_char_ptr = getelementptr i8, ptr %buf_ptr4, i64 %end_idx ; Carrega os valores %start_char = load i8, ptr %start_char_ptr @@ -410,18 +409,36 @@ swap_chars: ; Troca os caracteres store i8 %start_char, ptr %end_char_ptr ; Atualiza os índices - %next_start = add i32 %start_idx, 1 - %prev_end = sub i32 %end_idx, 1 - store i32 %next_start, ptr %start - store i32 %prev_end, ptr %end + %next_start = add i64 %start_idx, 1 + %prev_end = sub i64 %end_idx, 1 + store i64 %next_start, ptr %start + store i64 %prev_end, ptr %end br label %reverse_loop finalize_string: ; Finaliza a string - %i_val3 = load i32, ptr %i + %i_val3 = load i64, ptr %i %buf_ptr5 = load ptr, ptr %buffer - %str_loc3 = getelementptr i8, ptr %buf_ptr5, i32 %i_val3 + %str_loc3 = getelementptr i8, ptr %buf_ptr5, i64 %i_val3 store i8 0, ptr %str_loc3 ; Terminador nulo %final_buf = load ptr, ptr %buffer ret ptr %final_buf } + +declare i32 @sprintf(ptr %buffer, ptr %format, ...) #1 + +define ptr @ftos(double %x) { +entry: + ; Aloca espaço para o buffer de resultado + %buffer = alloca [128 x i8], align 1 + + ; Define a constante local para o formato "%f" + %format = alloca [4 x i8], align 1 + store [3 x i8] c"%f\00", ptr %format + + ; Chama o sprintf com a string de formato + call i32 @sprintf(ptr %buffer, ptr %format, double %x) + + ; Retorna o resultado final (buffer) com a string + ret ptr %buffer +}