| /* |
| * Copyright 2023 Google LLC |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| // A starting functions for simple kelvin programs. |
| |
| /** |
| * Entry point. |
| */ |
| .section ._init |
| .balign 4 |
| .global _start |
| .type _start, @function |
| _start: |
| ############################################### |
| # Put all scalar registers into a known state # |
| ############################################### |
| la sp, __stack_end__ |
| la gp, _global_pointer |
| mv tp, zero |
| mv t1, zero |
| mv t2, zero |
| mv s0, zero |
| mv s1, zero |
| mv a1, zero |
| mv a2, zero |
| mv a3, zero |
| mv a4, zero |
| mv a5, zero |
| mv a6, zero |
| mv a7, zero |
| mv s2, zero |
| mv s3, zero |
| mv s4, zero |
| mv s5, zero |
| mv s6, zero |
| mv s7, zero |
| mv s8, zero |
| mv s9, zero |
| mv s10, zero |
| mv s11, zero |
| mv t3, zero |
| mv t4, zero |
| mv t5, zero |
| mv t6, zero |
| |
| ############################################### |
| # Zero out all kelvin registers # |
| ############################################### |
| vdup.w.x.m v0, zero |
| vdup.w.x.m v4, zero |
| vdup.w.x.m v8, zero |
| vdup.w.x.m v12, zero |
| vdup.w.x.m v16, zero |
| vdup.w.x.m v20, zero |
| vdup.w.x.m v24, zero |
| vdup.w.x.m v28, zero |
| vdup.w.x.m v32, zero |
| vdup.w.x.m v36, zero |
| vdup.w.x.m v40, zero |
| vdup.w.x.m v44, zero |
| vdup.w.x.m v48, zero |
| vdup.w.x.m v52, zero |
| vdup.w.x.m v56, zero |
| vdup.w.x.m v60, zero |
| acset.v v48, v0 |
| adwinit.v v48, v0 |
| |
| # Zero out the bss section |
| la a0, __bss_start__ |
| la a1, __bss_end__ |
| call crt_section_clear |
| |
| # Initialize the heap ptr after clearing BSS |
| la s0, __heap_start__ |
| sw s0, _heap_ptr, s1 |
| |
| # Initialize arrays |
| la s0, __init_array_start__ |
| la s1, __init_array_end__ |
| bgeu s0, s1, init_array_loop_end |
| init_array_loop: |
| lw t0, 0(s0) |
| jalr t0 |
| addi s0, s0, 0x4 |
| bltu s0, s1, init_array_loop |
| init_array_loop_end: |
| |
| # Set up sentinel value in _ret |
| # If we see this after an ebreak, |
| # the break source is unlikely to |
| # be a clean return from main. |
| la t0, _ret |
| li a0, 0x0badd00d |
| sw a0, 0(t0) |
| |
| ############# |
| # Call main # |
| ############# |
| li a0, 0 # argv |
| li a1, 0 # argc |
| la ra, main |
| jalr ra, ra |
| # Store the application's return value at _ret |
| la t0, _ret |
| sw a0, 0(t0) |
| flushall |
| beqz a0, success |
| failure: |
| ebreak |
| j loop |
| success: |
| mpause # Kelvin end of program op |
| loop: |
| j loop |