Created
April 14, 2025 04:20
-
-
Save miguel-tubac/08460836e34dc5ff206f729aa838e4ea to your computer and use it in GitHub Desktop.
StandardLibrary
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //Aca estan las instrucciones estandares de ARM64 | |
| public class StandardLibrary | |
| { | |
| private readonly HashSet<string> UsedFunctions = new HashSet<string>(); | |
| public void Use(string function) | |
| { | |
| UsedFunctions.Add(function); | |
| } | |
| public string GetFunctionDefinitions() | |
| { | |
| var functions = new List<string>(); | |
| foreach (var function in UsedFunctions) | |
| { | |
| if (FunctionDefinitions.TryGetValue(function, out var definition)) | |
| { | |
| functions.Add(definition); | |
| } | |
| } | |
| return string.Join("\n\n", functions); | |
| } | |
| private readonly static Dictionary<string, string> FunctionDefinitions = new Dictionary<string, string> | |
| { | |
| { "print_integer", @" | |
| //-------------------------------------------------------------- | |
| // print_integer - Prints a signed integer to stdout | |
| // | |
| // Input: | |
| // x0 - The integer value to print | |
| //-------------------------------------------------------------- | |
| print_integer: | |
| // Save registers | |
| stp x29, x30, [sp, #-16]! // Save frame pointer and link register | |
| stp x19, x20, [sp, #-16]! // Save callee-saved registers | |
| stp x21, x22, [sp, #-16]! | |
| stp x23, x24, [sp, #-16]! | |
| stp x25, x26, [sp, #-16]! | |
| stp x27, x28, [sp, #-16]! | |
| // Check if number is negative | |
| mov x19, x0 // Save original number | |
| cmp x19, #0 // Compare with zero | |
| bge positive_number // Branch if greater or equal to zero | |
| // Handle negative number | |
| mov x0, #1 // fd = 1 (stdout) | |
| adr x1, minus_sign // Address of minus sign | |
| mov x2, #1 // Length = 1 | |
| mov w8, #64 // Syscall write | |
| svc #0 | |
| neg x19, x19 // Make number positive | |
| positive_number: | |
| // Prepare buffer for converting result to ASCII | |
| sub sp, sp, #32 // Reserve space on stack | |
| mov x22, sp // x22 points to buffer | |
| // Initialize digit counter | |
| mov x23, #0 // Digit counter | |
| // Handle special case for zero | |
| cmp x19, #0 | |
| bne convert_loop | |
| // If number is zero, just write '0' | |
| mov w24, #48 // ASCII '0' | |
| strb w24, [x22, x23] // Store in buffer | |
| add x23, x23, #1 // Increment counter | |
| b print_result // Skip conversion loop | |
| convert_loop: | |
| // Divide the number by 10 | |
| mov x24, #10 | |
| udiv x25, x19, x24 // x25 = x19 / 10 (quotient) | |
| msub x26, x25, x24, x19 // x26 = x19 - (x25 * 10) (remainder) | |
| // Convert remainder to ASCII and store in buffer | |
| add x26, x26, #48 // Convert to ASCII ('0' = 48) | |
| strb w26, [x22, x23] // Store digit in buffer | |
| add x23, x23, #1 // Increment digit counter | |
| // Prepare for next iteration | |
| mov x19, x25 // Quotient becomes the new number | |
| cbnz x19, convert_loop // If number is not zero, continue | |
| // Reverse the buffer since digits are in reverse order | |
| mov x27, #0 // Start index | |
| reverse_loop: | |
| sub x28, x23, x27 // x28 = length - current index | |
| sub x28, x28, #1 // x28 = length - current index - 1 | |
| cmp x27, x28 // Compare indices | |
| bge print_result // If crossed, finish reversing | |
| // Swap characters | |
| ldrb w24, [x22, x27] // Load character from start | |
| ldrb w25, [x22, x28] // Load character from end | |
| strb w25, [x22, x27] // Store end character at start | |
| strb w24, [x22, x28] // Store start character at end | |
| add x27, x27, #1 // Increment start index | |
| b reverse_loop // Continue reversing | |
| print_result: | |
| // Add newline | |
| mov w24, #10 // Newline character | |
| strb w24, [x22, x23] // Add to end of buffer | |
| add x23, x23, #1 // Increment counter | |
| // Print the result | |
| mov x0, #1 // fd = 1 (stdout) | |
| mov x1, x22 // Buffer address | |
| mov x2, x23 // Buffer length | |
| mov w8, #64 // Syscall write | |
| svc #0 | |
| // Clean up and restore registers | |
| add sp, sp, #32 // Free buffer space | |
| ldp x27, x28, [sp], #16 // Restore callee-saved registers | |
| ldp x25, x26, [sp], #16 | |
| ldp x23, x24, [sp], #16 | |
| ldp x21, x22, [sp], #16 | |
| ldp x19, x20, [sp], #16 | |
| ldp x29, x30, [sp], #16 // Restore frame pointer and link register | |
| ret // Return to caller | |
| minus_sign: | |
| .ascii ""-"" // Minus sign" | |
| }, | |
| { "print_string", @" | |
| //-------------------------------------------------------------- | |
| // print_string - Prints a null-terminated string to stdout | |
| // | |
| // Input: | |
| // x0 - The address of the null-terminated string to print | |
| //-------------------------------------------------------------- | |
| print_string: | |
| // Save link register and other registers we'll use | |
| stp x29, x30, [sp, #-16]! | |
| stp x19, x20, [sp, #-16]! | |
| // x19 will hold the string address | |
| mov x19, x0 | |
| print_loop: | |
| // Load a byte from the string | |
| ldrb w20, [x19] | |
| // Check if it's the null terminator (0) | |
| cbz w20, print_done | |
| // Prepare for write syscall | |
| mov x0, #1 // File descriptor: 1 for stdout | |
| mov x1, x19 // Address of the character to print | |
| mov x2, #1 // Length: 1 byte | |
| mov x8, #64 // syscall: write (64 on ARM64) | |
| svc #0 // Make the syscall | |
| // Move to the next character | |
| add x19, x19, #1 | |
| // Continue the loop | |
| b print_loop | |
| print_done: | |
| // Print newline character | |
| ldr x1, =newline // Address of newline character | |
| mov x0, #1 // File descriptor: stdout | |
| mov x2, #1 // Length of 1 byte | |
| mov x8, #64 // syscall: write | |
| svc #0 | |
| // Restore saved registers | |
| ldp x19, x20, [sp], #16 | |
| ldp x29, x30, [sp], #16 | |
| ret | |
| " }, | |
| {"string_to_double", @" | |
| // Función que convierte cadena (en x1) a double (en d0) | |
| string_to_double: | |
| stp x29, x30, [sp, #-16]! | |
| mov x29, sp | |
| // Cargar zero a d0 | |
| adrp x8, zero | |
| add x8, x8, :lo12:zero | |
| ldr d0, [x8] | |
| // Cargar one a d2 | |
| adrp x8, one | |
| add x8, x8, :lo12:one | |
| ldr d2, [x8] | |
| mov w2, #0 // Modo decimal | |
| mov w4, #0 // Signo | |
| // Verificar signo negativo | |
| ldrb w3, [x1] | |
| cmp w3, #'-' | |
| bne loop_convert | |
| mov w4, #1 | |
| add x1, x1, #1 | |
| loop_convert: | |
| ldrb w3, [x1], #1 | |
| cmp w3, #0 | |
| beq end_convert | |
| cmp w3, #'.' | |
| bne not_decimal_point | |
| mov w2, #1 | |
| b loop_convert | |
| not_decimal_point: | |
| cmp w3, #'0' | |
| blt loop_convert | |
| cmp w3, #'9' | |
| bgt loop_convert | |
| sub w3, w3, #'0' | |
| scvtf d3, w3 | |
| cmp w2, #0 | |
| beq process_integer | |
| // Parte decimal | |
| adrp x8, ten | |
| add x8, x8, :lo12:ten | |
| ldr d4, [x8] | |
| fmul d2, d2, d4 | |
| fdiv d3, d3, d2 | |
| fadd d0, d0, d3 | |
| b loop_convert | |
| process_integer: | |
| adrp x8, ten | |
| add x8, x8, :lo12:ten | |
| ldr d4, [x8] | |
| fmul d0, d0, d4 | |
| fadd d0, d0, d3 | |
| b loop_convert | |
| end_convert: | |
| cmp w4, #1 | |
| bne done_convert | |
| adrp x8, neg_one | |
| add x8, x8, :lo12:neg_one | |
| ldr d1, [x8] | |
| fmul d0, d0, d1 | |
| done_convert: | |
| ldp x29, x30, [sp], #16 | |
| ret | |
| "}, | |
| {"print_double", @" | |
| //La endrada debe de ingresar en el registro d0 | |
| print_double: | |
| stp x29, x30, [sp, #-80]! | |
| mov x29, sp | |
| // Inicializar buffer | |
| add x1, sp, #16 | |
| mov x20, x1 | |
| // Manejar signo | |
| adrp x8, zero | |
| add x8, x8, :lo12:zero | |
| ldr d1, [x8] | |
| fcmp d0, d1 | |
| bge positive | |
| mov w3, #'-' | |
| strb w3, [x1], #1 | |
| adrp x8, neg_one | |
| add x8, x8, :lo12:neg_one | |
| ldr d1, [x8] | |
| fmul d0, d0, d1 | |
| mov x19, #1 | |
| b after_sign | |
| positive: | |
| mov x19, #0 | |
| after_sign: | |
| // Redondear | |
| adrp x21, round_const | |
| add x21, x21, :lo12:round_const | |
| ldr d3, [x21] | |
| fadd d0, d0, d3 | |
| // Separar parte entera y decimal | |
| frintz d1, d0 | |
| fsub d2, d0, d1 | |
| // Convertir parte entera | |
| mov x4, x1 | |
| convert_int_loop: | |
| adrp x22, ten | |
| add x22, x22, :lo12:ten | |
| ldr d4, [x22] | |
| fdiv d5, d1, d4 | |
| frintz d5, d5 | |
| fmul d6, d5, d4 | |
| fsub d6, d1, d6 | |
| fcvtzs w5, d6 | |
| add w5, w5, #'0' | |
| strb w5, [x1], #1 | |
| fmov d1, d5 | |
| adrp x8, zero | |
| add x8, x8, :lo12:zero | |
| ldr d8, [x8] | |
| fcmp d1, d8 | |
| bne convert_int_loop | |
| // Invertir dígitos | |
| mov x5, x4 | |
| sub x6, x1, #1 | |
| reverse_int_loop: | |
| cmp x5, x6 | |
| bge reverse_done | |
| ldrb w7, [x5] | |
| ldrb w8, [x6] | |
| strb w8, [x5], #1 | |
| strb w7, [x6], #-1 | |
| b reverse_int_loop | |
| reverse_done: | |
| // Añadir punto decimal | |
| adrp x9, point | |
| add x9, x9, :lo12:point | |
| ldrb w9, [x9] | |
| strb w9, [x1], #1 | |
| // Convertir parte decimal | |
| mov w10, #6 | |
| convert_decimal_loop: | |
| cbz w10, decimal_done | |
| adrp x22, ten | |
| add x22, x22, :lo12:ten | |
| ldr d4, [x22] | |
| fmul d2, d2, d4 | |
| frintz d5, d2 | |
| fcvtzs w11, d5 | |
| cmp w10, #1 | |
| bne no_final_round | |
| fsub d6, d2, d5 | |
| adrp x23, half | |
| add x23, x23, :lo12:half | |
| ldr d7, [x23] | |
| fcmp d6, d7 | |
| blt no_final_round | |
| add w11, w11, #1 | |
| no_final_round: | |
| cmp w11, #10 | |
| blt store_decimal | |
| mov w11, #9 | |
| store_decimal: | |
| fsub d2, d2, d5 | |
| add w11, w11, #'0' | |
| strb w11, [x1], #1 | |
| sub w10, w10, #1 | |
| b convert_decimal_loop | |
| decimal_done: | |
| // Añadir salto de línea | |
| adrp x12, newline | |
| add x12, x12, :lo12:newline | |
| ldrb w12, [x12] | |
| strb w12, [x1], #1 | |
| // Calcular longitud | |
| sub x2, x1, x20 | |
| cmp x19, #1 | |
| bne print_output | |
| sub x20, x20, #1 | |
| add x2, x2, #1 | |
| print_output: | |
| // Escribir | |
| mov x0, #1 | |
| mov x1, x20 | |
| mov x8, #64 | |
| svc #0 | |
| ldp x29, x30, [sp], #80 | |
| ret | |
| "} | |
| }; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment