Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save miguel-tubac/08460836e34dc5ff206f729aa838e4ea to your computer and use it in GitHub Desktop.

Select an option

Save miguel-tubac/08460836e34dc5ff206f729aa838e4ea to your computer and use it in GitHub Desktop.
StandardLibrary
//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