Coder Social home page Coder Social logo

venus's Introduction

Web: Build Status

Java: Build Status

Venus is a RISC-V instruction set simulator built for education.

Using Venus

Venus is available online.

Features

  • RV32IM
  • Single-step debugging with undo feature
  • Breakpoint debugging
  • View machine code and original instructions side-by-side
  • Several ecalls: including print and sbrk
  • Memory visualization
  • Basic External Package Management System

Resources

Credit

venus's People

Contributors

hiporox avatar kevinlin1 avatar kvakil avatar thaumicmekanism avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

venus's Issues

“Remote” Venus Debugging.

Make it so the web interface for venus can act as a remote debugger controlling a ‘link’ which is hosting the real debugger.

%hi & %lo not working

After successfully getting "print 42 to the console" working, I'm trying to write hello world, and am getting assembler errors. Here's my code, adapted from gcc -s:

	.data
Hello:
	.string	"hello, world!"
	.text
	.align	1
	.globl	main
__start:
	lui	a1, %hi(Hello)   <- here the error says "got 3 arguments but expected 2)
	addi	a1, a1, %lo(Hello)  <- here it says got 4 expected 3
	addi    a0, x0, 4 # print_string
	ecall
	addi    a1, x0, 0
	addi    a0, x0, 17 # exit2
	ecall

I've looked at the ISA (no mention of the %hi/lo directives), and other locations - this seems to be an underdocumented aspect of RISC-V, but the current use of it is taken from how risc-v-gcc does it. What am I doing wrong, or is this a bug?

Jalr Mismatch

This works:

jalr ra (0)s0

And it should produce an error.

FCLASS.S (.D) instruction is not working correctly

FCLASS.S or FCLASS.D instruction looks at a floating point value and determines what sort of a number it is. For example, does the value represents +0.0, -0.0, NaN, +infin, - infin etc..
According to the spec it should return the following values based on a floating point number and store it to a integer register.
FCLASS
But actually it is giving the following results

For +0.0, it gives value = 0x00000008 
But it should be value = 0x00000010
For -0.0, it gives `IllegalArgumentException: Count 'n' must be non-negative, but was -1. 
But it should be value = 0x00000008
For +infinity, it gives value = 0x00000040 
But it should be value = 0x00000080
For -infinity, it gives `NumberFormatException: Invalid number format: '00000000-8000000' 
But it should be value = 0x00000001

.
.
and I didn't checked other cases.

Example - Tracing Assembly Code

Is there any reason the following exact program is not showing the proper value of x5?

main:   
addi x11, x0, 0x3f5
sw x11, 0(x5)
lb x12, 1(x5)

This program comes from the lecture.

Circular shift behavior wrong

It seems that for R-type shift instructions, if rs2 is greater than 31, the shift will actually be circular (not consistently but that's the general behavior).

Minimal example:

li x2, 0xBEEF; li x3, 0x128; sra x2, x2, x3

I type mismatch

This works:

addi x0 x0 (0)

And it should produce an error.

Unable to use .equ with li pseudo instruction.

My environment is using the VS Code extension for venus on Windows 10. I am writing some code and came across an oddity of using .equ with the li pseudo instruction. the code looks like:

         .text
hash:    .globl   hash
         .equ     prime, 0x01000193
         .equ     seed, 0x811C9DC5
         li       a3, prime
         li       a0, seed

This results in the following error in the Venus Terminal:

AssemblerError: test.riscv:36: immediate value out of range: 16777619
li      a3, prime

However, when I remove the .equ and assign the values directly it is successful:

         .text
hash:    .globl   hash
         li       a3, 0x01000193
         li       a0, 0x811C9DC5

Looking at the riscv-asm-manual on github it appears what I'm trying to accomplish is the same as the example in the manual.

Error executing step-by-step code when encountering "ecall" instruction

--------------------
[ERROR] An uncaught error has occurred! Here are the details that may help solve this issue.

Error:
`SimulatorError: The heap has grown into the stack.

ID:
'step'!

`

Data:
{"venus":"true","trace_format":"%output%%0%\t%1%\t%2%\t%3%\t%4%\t%5%\t%6%\t%7%\t%8%\t%9%\t%10%\t%11%\t%12%\t%13%\t%14%\t%15%\t%16%\t%17%\t%18%\t%19%\t%20%\t%21%\t%22%\t%23%\t%24%\t%25%\t%26%\t%27%\t%28%\t%29%\t%30%\t%31%\t%line%\t%pc%\t%inst%\n","trace_base":"2","trace_totCommands":"-1","trace_maxSteps":"-1","trace_instFirst":"false","trace_wordAddressed":"false","trace_TwoStage":"false","history_limit":"-1","text_begin":"0","aligned_memory":"false","mutable_text":"true","ecall_exit_only":"false","set_regs_on_init":"true","simargs":"","enableCallingConvention":"false","prog":"# Compiled ChocoPy Program to RISC-V assembly\n# Execute (run or step-through) using the 'Simulator' tab above \n# Output will appear on the bottom-left of the simulator\n  .equiv @sbrk, 9\n  .equiv @print_string, 4\n  .equiv @print_char, 11\n  .equiv @print_int, 1\n  .equiv @exit2, 17\n  .equiv @read_string, 8\n  .equiv @fill_line_buffer, 18\n  .equiv @.__obj_size__, 4\n  .equiv @.__len__, 12\n  .equiv @.__int__, 12\n  .equiv @.__bool__, 12\n  .equiv @.__str__, 16\n  .equiv @.__elts__, 16\n  .equiv @error_div_zero, 2\n  .equiv @error_arg, 1\n  .equiv @error_oob, 3\n  .equiv @error_none, 4\n  .equiv @error_oom, 5\n  .equiv @error_nyi, 6\n  .equiv @listHeaderWords, 4\n  .equiv @strHeaderWords, 4\n  .equiv @bool.True, const_1\n  .equiv @bool.False, const_0\n\n.data\n\n.globl $object$prototype\n$object$prototype:\n  .word 0                                  # Type tag for class: object\n  .word 3                                  # Object size\n  .word $object$dispatchTable              # Pointer to dispatch table\n  .align 2\n\n.globl $int$prototype\n$int$prototype:\n  .word 1                                  # Type tag for class: int\n  .word 4                                  # Object size\n  .word $int$dispatchTable                 # Pointer to dispatch table\n  .word 0                                  # Initial value of attribute: __int__\n  .align 2\n\n.globl $bool$prototype\n$bool$prototype:\n  .word 2                                  # Type tag for class: bool\n  .word 4                                  # Object size\n  .word $bool$dispatchTable                # Pointer to dispatch table\n  .word 0                                  # Initial value of attribute: __bool__\n  .align 2\n\n.globl $str$prototype\n$str$prototype:\n  .word 3                                  # Type tag for class: str\n  .word 5                                  # Object size\n  .word $str$dispatchTable                 # Pointer to dispatch table\n  .word 0                                  # Initial value of attribute: __len__\n  .word 0                                  # Initial value of attribute: __str__\n  .align 2\n\n.globl $.list$prototype\n$.list$prototype:\n  .word -1                                 # Type tag for class: .list\n  .word 4                                  # Object size\n  .word 0                                  # Pointer to dispatch table\n  .word 0                                  # Initial value of attribute: __len__\n  .align 2\n\n.globl $object$dispatchTable\n$object$dispatchTable:\n  .word $object.__init__                   # Implementation for method: object.__init__\n\n.globl $int$dispatchTable\n$int$dispatchTable:\n  .word $object.__init__                   # Implementation for method: int.__init__\n\n.globl $bool$dispatchTable\n$bool$dispatchTable:\n  .word $object.__init__                   # Implementation for method: bool.__init__\n\n.globl $str$dispatchTable\n$str$dispatchTable:\n  .word $object.__init__                   # Implementation for method: str.__init__\n\n.text\n\n.globl main\nmain:\n  lui a0, 8192                             # Initialize heap size (in multiples of 4KB)\n  add s11, s11, a0                         # Save heap size\n  jal heap.init                            # Call heap.init routine\n  mv gp, a0                                # Initialize heap pointer\n  mv s10, gp                               # Set beginning of heap\n  add s11, s10, s11                        # Set end of heap (= start of heap + heap size)\n  mv ra, zero                              # No normal return from main program.\n  mv fp, zero                              # No preceding frame.\n  mv fp, zero                              # Top saved FP is 0.\n  mv ra, zero                              # No function return from top level.\n  addi sp, sp, [email protected]               # Reserve space for stack frame.\n  sw ra, @..main.size-4(sp)                # return address\n  sw fp, @..main.size-8(sp)                # control link\n  addi fp, sp, @..main.size                # New fp is at old SP.\n  jal initchars                            # Initialize one-character strings.\n  li a0, 4                                 # Load integer literal 4\n  sw a0, -28(fp)                           # Push argument 5 from last.\n  li a0, 8                                 # Load integer literal 8\n  sw a0, -32(fp)                           # Push argument 4 from last.\n  li a0, 15                                # Load integer literal 15\n  sw a0, -36(fp)                           # Push argument 3 from last.\n  li a0, 16                                # Load integer literal 16\n  sw a0, -40(fp)                           # Push argument 2 from last.\n  li a0, 23                                # Load integer literal 23\n  sw a0, -44(fp)                           # Push argument 1 from last.\n  li a0, 5                                 # Pass list length\n  sw a0, -48(fp)                           # Push argument 0 from last.\n  addi sp, fp, -48                         # Set SP to last argument.\n  jal conslist                             # Move values to new list object\n  addi sp, fp, [email protected]               # Set SP to stack frame top.\n  sw a0, -12(fp)                           # Push argument 1 from last.\n  li a0, 15                                # Load integer literal 15\n  sw a0, -16(fp)                           # Push argument 0 from last.\n  addi sp, fp, -16                         # Set SP to last argument.\n  jal $contains                            # Invoke function: contains\n  addi sp, fp, [email protected]               # Set SP to stack frame top.\n  beqz a0, label_2                         # Branch on false.\n  la a0, const_2                           # Load string literal\n  sw a0, -16(fp)                           # Push argument 0 from last.\n  addi sp, fp, -16                         # Set SP to last argument.\n  jal $print                               # Invoke function: print\n  addi sp, fp, [email protected]               # Set SP to stack frame top.\n  j label_1                                # Then body complete; jump to end-if\nlabel_2:                                   # Else body\n  la a0, const_3                           # Load string literal\n  sw a0, -16(fp)                           # Push argument 0 from last.\n  addi sp, fp, -16                         # Set SP to last argument.\n  jal $print                               # Invoke function: print\n  addi sp, fp, [email protected]               # Set SP to stack frame top.\nlabel_1:                                   # End of if-else statement\n  .equiv @..main.size, 48\nlabel_0:                                   # End of program\n  li a0, 10                                # Code for ecall: exit\n  ecall\n\n.globl $object.__init__\n$object.__init__:\n# Init method for type object.\t\n  mv a0, zero                              # `None` constant\n  jr ra                                    # Return\n\n.globl $print\n$print:\n# Function print\n  lw a0, 0(sp)                             # Load arg\n  beq a0, zero, print_6                    # None is an illegal argument\n  lw t0, 0(a0)                             # Get type tag of arg\n  li t1, 1                                 # Load type tag of `int`\n  beq t0, t1, print_7                      # Go to print(int)\n  li t1, 3                                 # Load type tag of `str`\n  beq t0, t1, print_8                      # Go to print(str)\n  li t1, 2                                 # Load type tag of `bool`\n  beq t0, t1, print_9                      # Go to print(bool)\nprint_6:                                   # Invalid argument\n  li a0, 1                                 # Exit code for: Invalid argument\n  la a1, const_4                           # Load error message as str\n  addi a1, a1, @.__str__                   # Load address of attribute __str__\n  j abort                                  # Abort\n\n# Printing bools\nprint_9:                                   # Print bool object in A0\n  lw a0, @.__bool__(a0)                    # Load attribute __bool__\n  beq a0, zero, print_10                   # Go to: print(False)\n  la a0, const_5                           # String representation: True\n  j print_8                                # Go to: print(str)\nprint_10:                                  # Print False object in A0\n  la a0, const_6                           # String representation: False\n  j print_8                                # Go to: print(str)\n\n# Printing strs.\nprint_8:                                   # Print str object in A0\n  addi a1, a0, @.__str__                   # Load address of attribute __str__\n  j print_11                               # Print the null-terminated string is now in A1\n  mv a0, zero                              # Load None\n  j print_5                                # Go to return\nprint_11:                                  # Print null-terminated string in A1\n  li a0, @print_string                     # Code for ecall: print_string\n  ecall                                    # Print string\n  li a1, 10                                # Load newline character\n  li a0, @print_char                       # Code for ecall: print_char\n  ecall                                    # Print character\n  j print_5                                # Go to return\n\n# Printing ints.\nprint_7:                                   # Print int object in A0\n  lw a1, @.__int__(a0)                     # Load attribute __int__\n  li a0, @print_int                        # Code for ecall: print_int\n  ecall                                    # Print integer\n  li a1, 10                                # Load newline character\n  li a0, 11                                # Code for ecall: print_char\n  ecall                                    # Print character\n\nprint_5:                                   # End of function\n  mv a0, zero                              # Load None\n  jr ra                                    # Return to caller\n\n.globl $len\n$len:\n# Function len\n      # We do not save/restore fp/ra for this function\n      # because we know that it does not use the stack or does not\n      # call other functions.\n\n  lw a0, 0(sp)                             # Load arg\n  beq a0, zero, len_12                     # None is an illegal argument\n  lw t0, 0(a0)                             # Get type tag of arg\n  li t1, 3                                 # Load type tag of `str`\n  beq t0, t1, len_13                       # Go to len(str)\n  li t1, -1                                # Load type tag for list objects\n  beq t0, t1, len_13                       # Go to len(list)\nlen_12:                                    # Invalid argument\n  li a0, @error_arg                        # Exit code for: Invalid argument\n  la a1, const_4                           # Load error message as str\n  addi a1, a1, @.__str__                   # Load address of attribute __str__\n  j abort                                  # Abort\nlen_13:                                    # Get length of string\n  lw a0, @.__len__(a0)                     # Load attribute: __len__\n  jr ra                                    # Return to caller\n\n.globl $input\n$input:\n\n  addi sp, sp, -16\n  sw ra, 12(sp)\n  sw fp, 8(sp)\n  sw s1, 4(sp)\n  addi fp, sp, 16\n  li a0, @fill_line_buffer\n  ecall\n  bgez a0, input_nonempty\n  la a0, $str$prototype\n  j input_done\ninput_nonempty:\n  mv s1, a0\n  addi t0, s1, 5\n  addi t0, t0, @.__str__\n  srli a1, t0, 2\n  la a0, $str$prototype\n  jal ra, alloc2\n  sw s1, @.__len__(a0)\n  mv a2, s1\n  mv s1, a0\n  addi a1, a0, @.__str__\n  li a0, @read_string\n  ecall\n  addi a0, a0, 1\n  sw a0, @.__len__(s1)\n  add t0, a0, s1\n  li t1, 10\n  sb t1, @.__str__-1(t0)\n  sb zero, @.__str__(t0)\n  mv a0, s1\ninput_done:\n  lw s1, -12(fp)\n  lw ra, -4(fp)\n  lw fp, -8(fp)\n  addi sp, sp, 16\n  jr ra\n\n.globl $contains\n$contains:\n  addi sp, sp, [email protected]             # Reserve space for stack frame.\n  sw ra, @contains.size-4(sp)              # return address\n  sw fp, @contains.size-8(sp)              # control link\n  addi fp, sp, @contains.size              # New fp is at old SP.\n  li a0, 0                                 # Load integer literal 0\n  sw a0, -12(fp)                           # local variable i\n  j label_6                                # Jump to loop test\nlabel_5:                                   # Top of while loop\n  lw a0, 4(fp)                             # Load var: contains.items\n  sw a0, -16(fp)                           # Push on stack slot 4\n  lw a0, -12(fp)                           # Load var: contains.i\n  lw a1, -16(fp)                           # Pop stack slot 4\n  bnez a1, label_8                         # Ensure not None\n  j error.None                             # Go to error handler\nlabel_8:                                   # Not None\n  lw t0, 12(a1)                            # Load attribute: __len__\n  bltu a0, t0, label_9                     # Ensure 0 <= index < len\n  j error.OOB                              # Go to error handler\nlabel_9:                                   # Index within bounds\n  addi a0, a0, 4                           # Compute list element offset in words\n  li t0, 4                                 # Word size in bytes\n  mul a0, a0, t0                           # Compute list element offset in bytes\n  add a0, a1, a0                           # Pointer to list element\n  lw a0, 0(a0)                             # Get list element\n  sw a0, -16(fp)                           # Push on stack slot 4\n  lw a0, 0(fp)                             # Load var: contains.x\n  lw t0, -16(fp)                           # Pop stack slot 4\n  bne t0, a0, label_7                      # Branch on not ==\n  li a0, 1                                 # Load boolean literal: true\n  j label_4                                # Go to return\nlabel_7:                                   # End of if-else statement\n  lw a0, -12(fp)                           # Load var: contains.i\n  sw a0, -16(fp)                           # Push on stack slot 4\n  li a0, 1                                 # Load integer literal 1\n  lw t0, -16(fp)                           # Pop stack slot 4\n  add a0, t0, a0                           # Operator +\n  sw a0, -12(fp)                           # Assign var: contains.i\nlabel_6:                                   # Test loop condition\n  lw a0, -12(fp)                           # Load var: contains.i\n  sw a0, -16(fp)                           # Push on stack slot 4\n  lw a0, 4(fp)                             # Load var: contains.items\n  sw a0, -32(fp)                           # Push argument 0 from last.\n  addi sp, fp, -32                         # Set SP to last argument.\n  jal $len                                 # Invoke function: len\n  addi sp, fp, [email protected]             # Set SP to stack frame top.\n  lw t0, -16(fp)                           # Pop stack slot 4\n  blt t0, a0, label_5                      # Branch on <\n  li a0, 0                                 # Load boolean literal: false\n  j label_4                                # Go to return\n  mv a0, zero                              # Load None\n  j label_4                                # Jump to function epilogue\nlabel_4:                                   # Epilogue\n  .equiv @contains.size, 32\n  lw ra, -4(fp)                            # Get return address\n  lw fp, -8(fp)                            # Use control link to restore caller's fp\n  addi sp, sp, @contains.size              # Restore stack pointer\n  jr ra                                    # Return to caller\n\n.globl alloc\nalloc:\n# Runtime support function alloc.\n        # Prototype address is in a0.\n  lw a1, 4(a0)                             # Get size of object in words\n  j alloc2                                 # Allocate object with exact size\n\n.globl alloc2\nalloc2:\n# Runtime support function alloc2 (realloc).\n        # Prototype address is in a0.\n        # Number of words to allocate is in a1.\n  li a2, 4                                 # Word size in bytes\n  mul a2, a1, a2                           # Calculate number of bytes to allocate\n  add a2, gp, a2                           # Estimate where GP will move\n  bgeu a2, s11, alloc2_15                  # Go to OOM handler if too large\n  lw t0, @.__obj_size__(a0)                # Get size of object in words\n  mv t2, a0                                # Initialize src ptr\n  mv t3, gp                                # Initialize dest ptr\nalloc2_16:                                 # Copy-loop header\n  lw t1, 0(t2)                             # Load next word from src\n  sw t1, 0(t3)                             # Store next word to dest\n  addi t2, t2, 4                           # Increment src\n  addi t3, t3, 4                           # Increment dest\n  addi t0, t0, -1                          # Decrement counter\n  bne t0, zero, alloc2_16                  # Loop if more words left to copy\n  mv a0, gp                                # Save new object's address to return\n  sw a1, @.__obj_size__(a0)                # Set size of new object in words\n                                           # (same as requested size)\n  mv gp, a2                                # Set next free slot in the heap\n  jr ra                                    # Return to caller\nalloc2_15:                                 # OOM handler\n  li a0, @error_oom                        # Exit code for: Out of memory\n  la a1, const_7                           # Load error message as str\n  addi a1, a1, @.__str__                   # Load address of attribute __str__\n  j abort                                  # Abort\n\n.globl abort\nabort:\n# Runtime support function abort (does not return).\n  mv t0, a0                                # Save exit code in temp\n  li a0, @print_string                     # Code for print_string ecall\n  ecall                                    # Print error message in a1\n  li a1, 10                                # Load newline character\n  li a0, @print_char                       # Code for print_char ecall\n  ecall                                    # Print newline\n  mv a1, t0                                # Move exit code to a1\n  li a0, @exit2                            # Code for exit2 ecall\n  ecall                                    # Exit with code\nabort_17:                                  # Infinite loop\n  j abort_17                               # Prevent fallthrough\n\n.globl heap.init\nheap.init:\n# Runtime support function heap.init.\n  mv a1, a0                                # Move requested size to A1\n  li a0, @sbrk                             # Code for ecall: sbrk\n  ecall                                    # Request A1 bytes\n  jr ra                                    # Return to caller\n\n.globl concat\nconcat:\n\n        addi sp, sp, -32\n        sw ra, 28(sp)\n        sw fp, 24(sp)\n        addi fp, sp, 32\n\tsw s1, -12(fp)\n        sw s2, -16(fp)\n        sw s3, -20(fp)\n\tsw s4, -24(fp)\n        sw s5, -28(fp)\n        lw t0, 4(fp)\n        lw t1, 0(fp)\n        beqz t0, concat_none\n        beqz t1, concat_none\n        lw t0, @.__len__(t0)\n        lw t1, @.__len__(t1)\n        add s5, t0, t1\n        addi a1, s5, @listHeaderWords\n        la a0, $.list$prototype\n        jal alloc2\n        sw s5, @.__len__(a0)\n\tmv s5, a0\n        addi s3, s5, @.__elts__\n        lw s1, 4(fp)\n\tlw s2, @.__len__(s1)\n        addi s1, s1, @.__elts__\n\tlw s4, 12(fp)\nconcat_1:\n        beqz s2, concat_2\n        lw a0, 0(s1)\n\tjalr ra, s4, 0\n        sw a0, 0(s3)\n        addi s2, s2, -1\n        addi s1, s1, 4\n        addi s3, s3, 4\n        j concat_1\nconcat_2:\n        lw s1, 0(fp)\n        lw s2, @.__len__(s1)\n        addi s1, s1, @.__elts__\n\tlw s4, 8(fp)\nconcat_3:\n        beqz s2, concat_4\n        lw a0, 0(s1)\n\tjalr ra, s4, 0\n        sw a0, 0(s3)\n        addi s2, s2, -1\n        addi s1, s1, 4\n        addi s3, s3, 4\n        j concat_3\nconcat_4:\n\tmv a0, s5\n        lw s1, -12(fp)\n        lw s2, -16(fp)\n        lw s3, -20(fp)\n\tlw s4, -24(fp)\n        lw s5, -28(fp)\n        lw ra, -4(fp)\n        lw fp, -8(fp)\n        addi sp, sp, 32\n        jr ra\nconcat_none:\n        j error.None\n\n\n.globl conslist\nconslist:\n\n        addi sp, sp, -8\n        sw ra, 4(sp)\n        sw fp, 0(sp)\n        addi fp, sp, 8\n        lw a1, 0(fp)\n        la a0, $.list$prototype\n        beqz a1, conslist_done\n        addi a1, a1, @listHeaderWords\n        jal alloc2\n        lw t0, 0(fp)\n        sw t0, @.__len__(a0)\n        slli t1, t0, 2\n        add t1, t1, fp\n        addi t2, a0, @.__elts__\nconslist_1:\n        lw t3, 0(t1)\n        sw t3, 0(t2)\n        addi t1, t1, -4\n        addi t2, t2, 4\n        addi t0, t0, -1\n        bnez t0, conslist_1\nconslist_done:\n        lw ra, -4(fp)\n        lw fp, -8(fp)\n        addi sp, sp, 8\n        jr ra\n\n\n.globl strcat\nstrcat:\n\n        addi sp, sp, -12\n        sw ra, 8(sp)\n        sw fp, 4(sp)\n        addi fp, sp, 12\n        lw t0, 4(fp)\n        lw t1, 0(fp)\n        lw t0, @.__len__(t0)\n        beqz t0, strcat_4\n        lw t1, @.__len__(t1)\n        beqz t1, strcat_5\n        add t1, t0, t1\n        sw t1, -12(fp)\n        addi t1, t1, 4\n        srli t1, t1, 2\n        addi a1, t1, @listHeaderWords\n        la a0, $str$prototype\n        jal alloc2\n        lw t0, -12(fp)\n        sw t0, @.__len__(a0)\n        addi t2, a0, 16\n        lw t0, 4(fp)\n        lw t1, @.__len__(t0)\n        addi t0, t0, @.__str__\nstrcat_1:\n        beqz t1, strcat_2\n        lbu t3, 0(t0)\n        sb t3, 0(t2)\n        addi t1, t1, -1\n        addi t0, t0, 1\n        addi t2, t2, 1\n        j strcat_1\nstrcat_2:\n        lw t0, 0(fp)\n        lw t1, 12(t0)\n        addi t0, t0, 16\nstrcat_3:\n        beqz t1, strcat_6\n        lbu t3, 0(t0)\n        sb t3, 0(t2)\n        addi t1, t1, -1\n        addi t0, t0, 1\n        addi t2, t2, 1\n        j strcat_3\nstrcat_4:\n        lw a0, 0(fp)\n        j strcat_7\nstrcat_5:\n        lw a0, 4(fp)\n        j strcat_7\nstrcat_6:\n        sb zero, 0(t2)\nstrcat_7:\n        lw ra, -4(fp)\n        lw fp, -8(fp)\n        addi sp, sp, 12\n        jr ra\n\n\n.globl streql\nstreql:\n\n        addi sp, sp, -8\n        sw ra, 4(sp)\n        sw fp, 0(sp)\n        addi fp, sp, 8\n        lw a1, 4(fp)\n        lw a2, 0(fp)\n        lw t0, @.__len__(a1)\n        lw t1, @.__len__(a2)\n        bne t0, t1, streql_no\nstreql_1:\n        lbu t2, @.__str__(a1)\n        lbu t3, @.__str__(a2)\n        bne t2, t3, streql_no\n        addi a1, a1, 1\n        addi a2, a2, 1\n        addi t0, t0, -1\n        bgtz t0, streql_1\n        li a0, 1\n        j streql_end\nstreql_no:\n        xor a0, a0, a0\nstreql_end:\n        lw ra, -4(fp)\n        lw fp, -8(fp)\n        addi sp, sp, 8\n        jr ra\n\n\n.globl strneql\nstrneql:\n\n        addi sp, sp, -8\n        sw ra, 4(sp)\n        sw fp, 0(sp)\n        addi fp, sp, 8\n        lw a1, 4(fp)\n        lw a2, 0(fp)\n        lw t0, @.__len__(a1)\n        lw t1, @.__len__(a2)\n        bne t0, t1, strneql_yes\nstrneql_1:\n        lbu t2, @.__str__(a1)\n        lbu t3, @.__str__(a2)\n        bne t2, t3, strneql_yes\n        addi a1, a1, 1\n        addi a2, a2, 1\n        addi t0, t0, -1\n        bgtz t0, strneql_1\n        xor a0, a0, a0\n        j strneql_end\nstrneql_yes:\n        li a0, 1\nstrneql_end:\n        lw ra, -4(fp)\n        lw fp, -8(fp)\n        addi sp, sp, 8\n        jr ra\n\n\n.globl makeint\nmakeint:\n\n        addi sp, sp, -8\n        sw ra, 4(sp)\n        sw a0, 0(sp)\n        la a0, $int$prototype\n        jal ra, alloc\n        lw t0, 0(sp)\n        sw t0, @.__int__(a0)\n        lw ra, 4(sp)\n        addi sp, sp, 8\n        jr ra\n\n\n.globl makebool\nmakebool:\n\n\tslli a0, a0, 4\n        la t0, @bool.False\n        add a0, a0, t0\n\tjr ra\n\n\n.globl noconv\nnoconv:\n\n        jr ra\n\n\n.globl initchars\ninitchars:\n\n        jr ra\n\n\n.globl error.None\nerror.None:\n  li a0, 4                                 # Exit code for: Operation on None\n  la a1, const_8                           # Load error message as str\n  addi a1, a1, 16                          # Load address of attribute __str__\n  j abort                                  # Abort\n\n.globl error.Div\nerror.Div:\n  li a0, 2                                 # Exit code for: Division by zero\n  la a1, const_9                           # Load error message as str\n  addi a1, a1, 16                          # Load address of attribute __str__\n  j abort                                  # Abort\n\n.globl error.OOB\nerror.OOB:\n  li a0, 3                                 # Exit code for: Index out of bounds\n  la a1, const_10                          # Load error message as str\n  addi a1, a1, 16                          # Load address of attribute __str__\n  j abort                                  # Abort\n\n.data\n\n.globl const_0\nconst_0:\n  .word 2                                  # Type tag for class: bool\n  .word 4                                  # Object size\n  .word $bool$dispatchTable                # Pointer to dispatch table\n  .word 0                                  # Constant value of attribute: __bool__\n  .align 2\n\n.globl const_1\nconst_1:\n  .word 2                                  # Type tag for class: bool\n  .word 4                                  # Object size\n  .word $bool$dispatchTable                # Pointer to dispatch table\n  .word 1                                  # Constant value of attribute: __bool__\n  .align 2\n\n.globl const_3\nconst_3:\n  .word 3                                  # Type tag for class: str\n  .word 8                                  # Object size\n  .word $str$dispatchTable                 # Pointer to dispatch table\n  .word 15                                 # Constant value of attribute: __len__\n  .string \"Item not found.\"                # Constant value of attribute: __str__\n  .align 2\n\n.globl const_9\nconst_9:\n  .word 3                                  # Type tag for class: str\n  .word 9                                  # Object size\n  .word $str$dispatchTable                 # Pointer to dispatch table\n  .word 16                                 # Constant value of attribute: __len__\n  .string \"Division by zero\"               # Constant value of attribute: __str__\n  .align 2\n\n.globl const_7\nconst_7:\n  .word 3                                  # Type tag for class: str\n  .word 8                                  # Object size\n  .word $str$dispatchTable                 # Pointer to dispatch table\n  .word 13                                 # Constant value of attribute: __len__\n  .string \"Out of memory\"                  # Constant value of attribute: __str__\n  .align 2\n\n.globl const_10\nconst_10:\n  .word 3                                  # Type tag for class: str\n  .word 9                                  # Object size\n  .word $str$dispatchTable                 # Pointer to dispatch table\n  .word 19                                 # Constant value of attribute: __len__\n  .string \"Index out of bounds\"            # Constant value of attribute: __str__\n  .align 2\n\n.globl const_5\nconst_5:\n  .word 3                                  # Type tag for class: str\n  .word 6                                  # Object size\n  .word $str$dispatchTable                 # Pointer to dispatch table\n  .word 4                                  # Constant value of attribute: __len__\n  .string \"True\"                           # Constant value of attribute: __str__\n  .align 2\n\n.globl const_8\nconst_8:\n  .word 3                                  # Type tag for class: str\n  .word 9                                  # Object size\n  .word $str$dispatchTable                 # Pointer to dispatch table\n  .word 17                                 # Constant value of attribute: __len__\n  .string \"Operation on None\"              # Constant value of attribute: __str__\n  .align 2\n\n.globl const_2\nconst_2:\n  .word 3                                  # Type tag for class: str\n  .word 7                                  # Object size\n  .word $str$dispatchTable                 # Pointer to dispatch table\n  .word 11                                 # Constant value of attribute: __len__\n  .string \"Item found!\"                    # Constant value of attribute: __str__\n  .align 2\n\n.globl const_4\nconst_4:\n  .word 3                                  # Type tag for class: str\n  .word 9                                  # Object size\n  .word $str$dispatchTable                 # Pointer to dispatch table\n  .word 16                                 # Constant value of attribute: __len__\n  .string \"Invalid argument\"               # Constant value of attribute: __str__\n  .align 2\n\n.globl const_6\nconst_6:\n  .word 3                                  # Type tag for class: str\n  .word 6                                  # Object size\n  .word $str$dispatchTable                 # Pointer to dispatch table\n  .word 5                                  # Constant value of attribute: __len__\n  .string \"False\"                          # Constant value of attribute: __str__\n  .align 2\n","cache_levels":"1","cache_current_level":"1","cache_L1_associativity":"1","cache_L1_cacheBlockSize":"4","cache_L1_numberOfBlocks":"1","cache_L1_placementPol":"DIRECT_MAPPING","cache_L1_blockRepPolicy":"LRU","cache_L1_seed":"-7788879576802893459","cache_L1_attach":"false","activeFileinEditor":"","active_abs_file_name":"n","active_abs_file_path":"n","fileExplorerCurrentLocation":"","terminalCurrentLocation":""}
# Compiled ChocoPy Program to RISC-V assembly
# Execute (run or step-through) using the 'Simulator' tab above 
# Output will appear on the bottom-left of the simulator
  .equiv @sbrk, 9
  .equiv @print_string, 4
  .equiv @print_char, 11
  .equiv @print_int, 1
  .equiv @exit2, 17
  .equiv @read_string, 8
  .equiv @fill_line_buffer, 18
  .equiv @.__obj_size__, 4
  .equiv @.__len__, 12
  .equiv @.__int__, 12
  .equiv @.__bool__, 12
  .equiv @.__str__, 16
  .equiv @.__elts__, 16
  .equiv @error_div_zero, 2
  .equiv @error_arg, 1
  .equiv @error_oob, 3
  .equiv @error_none, 4
  .equiv @error_oom, 5
  .equiv @error_nyi, 6
  .equiv @listHeaderWords, 4
  .equiv @strHeaderWords, 4
  .equiv @bool.True, const_1
  .equiv @bool.False, const_0

.data

.globl $object$prototype
$object$prototype:
  .word 0                                  # Type tag for class: object
  .word 3                                  # Object size
  .word $object$dispatchTable              # Pointer to dispatch table
  .align 2

.globl $int$prototype
$int$prototype:
  .word 1                                  # Type tag for class: int
  .word 4                                  # Object size
  .word $int$dispatchTable                 # Pointer to dispatch table
  .word 0                                  # Initial value of attribute: __int__
  .align 2

.globl $bool$prototype
$bool$prototype:
  .word 2                                  # Type tag for class: bool
  .word 4                                  # Object size
  .word $bool$dispatchTable                # Pointer to dispatch table
  .word 0                                  # Initial value of attribute: __bool__
  .align 2

.globl $str$prototype
$str$prototype:
  .word 3                                  # Type tag for class: str
  .word 5                                  # Object size
  .word $str$dispatchTable                 # Pointer to dispatch table
  .word 0                                  # Initial value of attribute: __len__
  .word 0                                  # Initial value of attribute: __str__
  .align 2

.globl $.list$prototype
$.list$prototype:
  .word -1                                 # Type tag for class: .list
  .word 4                                  # Object size
  .word 0                                  # Pointer to dispatch table
  .word 0                                  # Initial value of attribute: __len__
  .align 2

.globl $object$dispatchTable
$object$dispatchTable:
  .word $object.__init__                   # Implementation for method: object.__init__

.globl $int$dispatchTable
$int$dispatchTable:
  .word $object.__init__                   # Implementation for method: int.__init__

.globl $bool$dispatchTable
$bool$dispatchTable:
  .word $object.__init__                   # Implementation for method: bool.__init__

.globl $str$dispatchTable
$str$dispatchTable:
  .word $object.__init__                   # Implementation for method: str.__init__

.text

.globl main
main:
  lui a0, 8192                             # Initialize heap size (in multiples of 4KB)
  add s11, s11, a0                         # Save heap size
  jal heap.init                            # Call heap.init routine
  mv gp, a0                                # Initialize heap pointer
  mv s10, gp                               # Set beginning of heap
  add s11, s10, s11                        # Set end of heap (= start of heap + heap size)
  mv ra, zero                              # No normal return from main program.
  mv fp, zero                              # No preceding frame.
  mv fp, zero                              # Top saved FP is 0.
  mv ra, zero                              # No function return from top level.
  addi sp, sp, -@..main.size               # Reserve space for stack frame.
  sw ra, @..main.size-4(sp)                # return address
  sw fp, @..main.size-8(sp)                # control link
  addi fp, sp, @..main.size                # New fp is at old SP.
  jal initchars                            # Initialize one-character strings.
  li a0, 4                                 # Load integer literal 4
  sw a0, -28(fp)                           # Push argument 5 from last.
  li a0, 8                                 # Load integer literal 8
  sw a0, -32(fp)                           # Push argument 4 from last.
  li a0, 15                                # Load integer literal 15
  sw a0, -36(fp)                           # Push argument 3 from last.
  li a0, 16                                # Load integer literal 16
  sw a0, -40(fp)                           # Push argument 2 from last.
  li a0, 23                                # Load integer literal 23
  sw a0, -44(fp)                           # Push argument 1 from last.
  li a0, 5                                 # Pass list length
  sw a0, -48(fp)                           # Push argument 0 from last.
  addi sp, fp, -48                         # Set SP to last argument.
  jal conslist                             # Move values to new list object
  addi sp, fp, -@..main.size               # Set SP to stack frame top.
  sw a0, -12(fp)                           # Push argument 1 from last.
  li a0, 15                                # Load integer literal 15
  sw a0, -16(fp)                           # Push argument 0 from last.
  addi sp, fp, -16                         # Set SP to last argument.
  jal $contains                            # Invoke function: contains
  addi sp, fp, -@..main.size               # Set SP to stack frame top.
  beqz a0, label_2                         # Branch on false.
  la a0, const_2                           # Load string literal
  sw a0, -16(fp)                           # Push argument 0 from last.
  addi sp, fp, -16                         # Set SP to last argument.
  jal $print                               # Invoke function: print
  addi sp, fp, -@..main.size               # Set SP to stack frame top.
  j label_1                                # Then body complete; jump to end-if
label_2:                                   # Else body
  la a0, const_3                           # Load string literal
  sw a0, -16(fp)                           # Push argument 0 from last.
  addi sp, fp, -16                         # Set SP to last argument.
  jal $print                               # Invoke function: print
  addi sp, fp, -@..main.size               # Set SP to stack frame top.
label_1:                                   # End of if-else statement
  .equiv @..main.size, 48
label_0:                                   # End of program
  li a0, 10                                # Code for ecall: exit
  ecall

.globl $object.__init__
$object.__init__:
# Init method for type object.	
  mv a0, zero                              # `None` constant
  jr ra                                    # Return

.globl $print
$print:
# Function print
  lw a0, 0(sp)                             # Load arg
  beq a0, zero, print_6                    # None is an illegal argument
  lw t0, 0(a0)                             # Get type tag of arg
  li t1, 1                                 # Load type tag of `int`
  beq t0, t1, print_7                      # Go to print(int)
  li t1, 3                                 # Load type tag of `str`
  beq t0, t1, print_8                      # Go to print(str)
  li t1, 2                                 # Load type tag of `bool`
  beq t0, t1, print_9                      # Go to print(bool)
print_6:                                   # Invalid argument
  li a0, 1                                 # Exit code for: Invalid argument
  la a1, const_4                           # Load error message as str
  addi a1, a1, @.__str__                   # Load address of attribute __str__
  j abort                                  # Abort

# Printing bools
print_9:                                   # Print bool object in A0
  lw a0, @.__bool__(a0)                    # Load attribute __bool__
  beq a0, zero, print_10                   # Go to: print(False)
  la a0, const_5                           # String representation: True
  j print_8                                # Go to: print(str)
print_10:                                  # Print False object in A0
  la a0, const_6                           # String representation: False
  j print_8                                # Go to: print(str)

# Printing strs.
print_8:                                   # Print str object in A0
  addi a1, a0, @.__str__                   # Load address of attribute __str__
  j print_11                               # Print the null-terminated string is now in A1
  mv a0, zero                              # Load None
  j print_5                                # Go to return
print_11:                                  # Print null-terminated string in A1
  li a0, @print_string                     # Code for ecall: print_string
  ecall                                    # Print string
  li a1, 10                                # Load newline character
  li a0, @print_char                       # Code for ecall: print_char
  ecall                                    # Print character
  j print_5                                # Go to return

# Printing ints.
print_7:                                   # Print int object in A0
  lw a1, @.__int__(a0)                     # Load attribute __int__
  li a0, @print_int                        # Code for ecall: print_int
  ecall                                    # Print integer
  li a1, 10                                # Load newline character
  li a0, 11                                # Code for ecall: print_char
  ecall                                    # Print character

print_5:                                   # End of function
  mv a0, zero                              # Load None
  jr ra                                    # Return to caller

.globl $len
$len:
# Function len
      # We do not save/restore fp/ra for this function
      # because we know that it does not use the stack or does not
      # call other functions.

  lw a0, 0(sp)                             # Load arg
  beq a0, zero, len_12                     # None is an illegal argument
  lw t0, 0(a0)                             # Get type tag of arg
  li t1, 3                                 # Load type tag of `str`
  beq t0, t1, len_13                       # Go to len(str)
  li t1, -1                                # Load type tag for list objects
  beq t0, t1, len_13                       # Go to len(list)
len_12:                                    # Invalid argument
  li a0, @error_arg                        # Exit code for: Invalid argument
  la a1, const_4                           # Load error message as str
  addi a1, a1, @.__str__                   # Load address of attribute __str__
  j abort                                  # Abort
len_13:                                    # Get length of string
  lw a0, @.__len__(a0)                     # Load attribute: __len__
  jr ra                                    # Return to caller

.globl $input
$input:

  addi sp, sp, -16
  sw ra, 12(sp)
  sw fp, 8(sp)
  sw s1, 4(sp)
  addi fp, sp, 16
  li a0, @fill_line_buffer
  ecall
  bgez a0, input_nonempty
  la a0, $str$prototype
  j input_done
input_nonempty:
  mv s1, a0
  addi t0, s1, 5
  addi t0, t0, @.__str__
  srli a1, t0, 2
  la a0, $str$prototype
  jal ra, alloc2
  sw s1, @.__len__(a0)
  mv a2, s1
  mv s1, a0
  addi a1, a0, @.__str__
  li a0, @read_string
  ecall
  addi a0, a0, 1
  sw a0, @.__len__(s1)
  add t0, a0, s1
  li t1, 10
  sb t1, @.__str__-1(t0)
  sb zero, @.__str__(t0)
  mv a0, s1
input_done:
  lw s1, -12(fp)
  lw ra, -4(fp)
  lw fp, -8(fp)
  addi sp, sp, 16
  jr ra

.globl $contains
$contains:
  addi sp, sp, -@contains.size             # Reserve space for stack frame.
  sw ra, @contains.size-4(sp)              # return address
  sw fp, @contains.size-8(sp)              # control link
  addi fp, sp, @contains.size              # New fp is at old SP.
  li a0, 0                                 # Load integer literal 0
  sw a0, -12(fp)                           # local variable i
  j label_6                                # Jump to loop test
label_5:                                   # Top of while loop
  lw a0, 4(fp)                             # Load var: contains.items
  sw a0, -16(fp)                           # Push on stack slot 4
  lw a0, -12(fp)                           # Load var: contains.i
  lw a1, -16(fp)                           # Pop stack slot 4
  bnez a1, label_8                         # Ensure not None
  j error.None                             # Go to error handler
label_8:                                   # Not None
  lw t0, 12(a1)                            # Load attribute: __len__
  bltu a0, t0, label_9                     # Ensure 0 <= index < len
  j error.OOB                              # Go to error handler
label_9:                                   # Index within bounds
  addi a0, a0, 4                           # Compute list element offset in words
  li t0, 4                                 # Word size in bytes
  mul a0, a0, t0                           # Compute list element offset in bytes
  add a0, a1, a0                           # Pointer to list element
  lw a0, 0(a0)                             # Get list element
  sw a0, -16(fp)                           # Push on stack slot 4
  lw a0, 0(fp)                             # Load var: contains.x
  lw t0, -16(fp)                           # Pop stack slot 4
  bne t0, a0, label_7                      # Branch on not ==
  li a0, 1                                 # Load boolean literal: true
  j label_4                                # Go to return
label_7:                                   # End of if-else statement
  lw a0, -12(fp)                           # Load var: contains.i
  sw a0, -16(fp)                           # Push on stack slot 4
  li a0, 1                                 # Load integer literal 1
  lw t0, -16(fp)                           # Pop stack slot 4
  add a0, t0, a0                           # Operator +
  sw a0, -12(fp)                           # Assign var: contains.i
label_6:                                   # Test loop condition
  lw a0, -12(fp)                           # Load var: contains.i
  sw a0, -16(fp)                           # Push on stack slot 4
  lw a0, 4(fp)                             # Load var: contains.items
  sw a0, -32(fp)                           # Push argument 0 from last.
  addi sp, fp, -32                         # Set SP to last argument.
  jal $len                                 # Invoke function: len
  addi sp, fp, -@contains.size             # Set SP to stack frame top.
  lw t0, -16(fp)                           # Pop stack slot 4
  blt t0, a0, label_5                      # Branch on <
  li a0, 0                                 # Load boolean literal: false
  j label_4                                # Go to return
  mv a0, zero                              # Load None
  j label_4                                # Jump to function epilogue
label_4:                                   # Epilogue
  .equiv @contains.size, 32
  lw ra, -4(fp)                            # Get return address
  lw fp, -8(fp)                            # Use control link to restore caller's fp
  addi sp, sp, @contains.size              # Restore stack pointer
  jr ra                                    # Return to caller

.globl alloc
alloc:
# Runtime support function alloc.
        # Prototype address is in a0.
  lw a1, 4(a0)                             # Get size of object in words
  j alloc2                                 # Allocate object with exact size

.globl alloc2
alloc2:
# Runtime support function alloc2 (realloc).
        # Prototype address is in a0.
        # Number of words to allocate is in a1.
  li a2, 4                                 # Word size in bytes
  mul a2, a1, a2                           # Calculate number of bytes to allocate
  add a2, gp, a2                           # Estimate where GP will move
  bgeu a2, s11, alloc2_15                  # Go to OOM handler if too large
  lw t0, @.__obj_size__(a0)                # Get size of object in words
  mv t2, a0                                # Initialize src ptr
  mv t3, gp                                # Initialize dest ptr
alloc2_16:                                 # Copy-loop header
  lw t1, 0(t2)                             # Load next word from src
  sw t1, 0(t3)                             # Store next word to dest
  addi t2, t2, 4                           # Increment src
  addi t3, t3, 4                           # Increment dest
  addi t0, t0, -1                          # Decrement counter
  bne t0, zero, alloc2_16                  # Loop if more words left to copy
  mv a0, gp                                # Save new object's address to return
  sw a1, @.__obj_size__(a0)                # Set size of new object in words
                                           # (same as requested size)
  mv gp, a2                                # Set next free slot in the heap
  jr ra                                    # Return to caller
alloc2_15:                                 # OOM handler
  li a0, @error_oom                        # Exit code for: Out of memory
  la a1, const_7                           # Load error message as str
  addi a1, a1, @.__str__                   # Load address of attribute __str__
  j abort                                  # Abort

.globl abort
abort:
# Runtime support function abort (does not return).
  mv t0, a0                                # Save exit code in temp
  li a0, @print_string                     # Code for print_string ecall
  ecall                                    # Print error message in a1
  li a1, 10                                # Load newline character
  li a0, @print_char                       # Code for print_char ecall
  ecall                                    # Print newline
  mv a1, t0                                # Move exit code to a1
  li a0, @exit2                            # Code for exit2 ecall
  ecall                                    # Exit with code
abort_17:                                  # Infinite loop
  j abort_17                               # Prevent fallthrough

.globl heap.init
heap.init:
# Runtime support function heap.init.
  mv a1, a0                                # Move requested size to A1
  li a0, @sbrk                             # Code for ecall: sbrk
  ecall                                    # Request A1 bytes
  jr ra                                    # Return to caller

.globl concat
concat:

        addi sp, sp, -32
        sw ra, 28(sp)
        sw fp, 24(sp)
        addi fp, sp, 32
	sw s1, -12(fp)
        sw s2, -16(fp)
        sw s3, -20(fp)
	sw s4, -24(fp)
        sw s5, -28(fp)
        lw t0, 4(fp)
        lw t1, 0(fp)
        beqz t0, concat_none
        beqz t1, concat_none
        lw t0, @.__len__(t0)
        lw t1, @.__len__(t1)
        add s5, t0, t1
        addi a1, s5, @listHeaderWords
        la a0, $.list$prototype
        jal alloc2
        sw s5, @.__len__(a0)
	mv s5, a0
        addi s3, s5, @.__elts__
        lw s1, 4(fp)
	lw s2, @.__len__(s1)
        addi s1, s1, @.__elts__
	lw s4, 12(fp)
concat_1:
        beqz s2, concat_2
        lw a0, 0(s1)
	jalr ra, s4, 0
        sw a0, 0(s3)
        addi s2, s2, -1
        addi s1, s1, 4
        addi s3, s3, 4
        j concat_1
concat_2:
        lw s1, 0(fp)
        lw s2, @.__len__(s1)
        addi s1, s1, @.__elts__
	lw s4, 8(fp)
concat_3:
        beqz s2, concat_4
        lw a0, 0(s1)
	jalr ra, s4, 0
        sw a0, 0(s3)
        addi s2, s2, -1
        addi s1, s1, 4
        addi s3, s3, 4
        j concat_3
concat_4:
	mv a0, s5
        lw s1, -12(fp)
        lw s2, -16(fp)
        lw s3, -20(fp)
	lw s4, -24(fp)
        lw s5, -28(fp)
        lw ra, -4(fp)
        lw fp, -8(fp)
        addi sp, sp, 32
        jr ra
concat_none:
        j error.None


.globl conslist
conslist:

        addi sp, sp, -8
        sw ra, 4(sp)
        sw fp, 0(sp)
        addi fp, sp, 8
        lw a1, 0(fp)
        la a0, $.list$prototype
        beqz a1, conslist_done
        addi a1, a1, @listHeaderWords
        jal alloc2
        lw t0, 0(fp)
        sw t0, @.__len__(a0)
        slli t1, t0, 2
        add t1, t1, fp
        addi t2, a0, @.__elts__
conslist_1:
        lw t3, 0(t1)
        sw t3, 0(t2)
        addi t1, t1, -4
        addi t2, t2, 4
        addi t0, t0, -1
        bnez t0, conslist_1
conslist_done:
        lw ra, -4(fp)
        lw fp, -8(fp)
        addi sp, sp, 8
        jr ra


.globl strcat
strcat:

        addi sp, sp, -12
        sw ra, 8(sp)
        sw fp, 4(sp)
        addi fp, sp, 12
        lw t0, 4(fp)
        lw t1, 0(fp)
        lw t0, @.__len__(t0)
        beqz t0, strcat_4
        lw t1, @.__len__(t1)
        beqz t1, strcat_5
        add t1, t0, t1
        sw t1, -12(fp)
        addi t1, t1, 4
        srli t1, t1, 2
        addi a1, t1, @listHeaderWords
        la a0, $str$prototype
        jal alloc2
        lw t0, -12(fp)
        sw t0, @.__len__(a0)
        addi t2, a0, 16
        lw t0, 4(fp)
        lw t1, @.__len__(t0)
        addi t0, t0, @.__str__
strcat_1:
        beqz t1, strcat_2
        lbu t3, 0(t0)
        sb t3, 0(t2)
        addi t1, t1, -1
        addi t0, t0, 1
        addi t2, t2, 1
        j strcat_1
strcat_2:
        lw t0, 0(fp)
        lw t1, 12(t0)
        addi t0, t0, 16
strcat_3:
        beqz t1, strcat_6
        lbu t3, 0(t0)
        sb t3, 0(t2)
        addi t1, t1, -1
        addi t0, t0, 1
        addi t2, t2, 1
        j strcat_3
strcat_4:
        lw a0, 0(fp)
        j strcat_7
strcat_5:
        lw a0, 4(fp)
        j strcat_7
strcat_6:
        sb zero, 0(t2)
strcat_7:
        lw ra, -4(fp)
        lw fp, -8(fp)
        addi sp, sp, 12
        jr ra


.globl streql
streql:

        addi sp, sp, -8
        sw ra, 4(sp)
        sw fp, 0(sp)
        addi fp, sp, 8
        lw a1, 4(fp)
        lw a2, 0(fp)
        lw t0, @.__len__(a1)
        lw t1, @.__len__(a2)
        bne t0, t1, streql_no
streql_1:
        lbu t2, @.__str__(a1)
        lbu t3, @.__str__(a2)
        bne t2, t3, streql_no
        addi a1, a1, 1
        addi a2, a2, 1
        addi t0, t0, -1
        bgtz t0, streql_1
        li a0, 1
        j streql_end
streql_no:
        xor a0, a0, a0
streql_end:
        lw ra, -4(fp)
        lw fp, -8(fp)
        addi sp, sp, 8
        jr ra


.globl strneql
strneql:

        addi sp, sp, -8
        sw ra, 4(sp)
        sw fp, 0(sp)
        addi fp, sp, 8
        lw a1, 4(fp)
        lw a2, 0(fp)
        lw t0, @.__len__(a1)
        lw t1, @.__len__(a2)
        bne t0, t1, strneql_yes
strneql_1:
        lbu t2, @.__str__(a1)
        lbu t3, @.__str__(a2)
        bne t2, t3, strneql_yes
        addi a1, a1, 1
        addi a2, a2, 1
        addi t0, t0, -1
        bgtz t0, strneql_1
        xor a0, a0, a0
        j strneql_end
strneql_yes:
        li a0, 1
strneql_end:
        lw ra, -4(fp)
        lw fp, -8(fp)
        addi sp, sp, 8
        jr ra


.globl makeint
makeint:

        addi sp, sp, -8
        sw ra, 4(sp)
        sw a0, 0(sp)
        la a0, $int$prototype
        jal ra, alloc
        lw t0, 0(sp)
        sw t0, @.__int__(a0)
        lw ra, 4(sp)
        addi sp, sp, 8
        jr ra


.globl makebool
makebool:

	slli a0, a0, 4
        la t0, @bool.False
        add a0, a0, t0
	jr ra


.globl noconv
noconv:

        jr ra


.globl initchars
initchars:

        jr ra


.globl error.None
error.None:
  li a0, 4                                 # Exit code for: Operation on None
  la a1, const_8                           # Load error message as str
  addi a1, a1, 16                          # Load address of attribute __str__
  j abort                                  # Abort

.globl error.Div
error.Div:
  li a0, 2                                 # Exit code for: Division by zero
  la a1, const_9                           # Load error message as str
  addi a1, a1, 16                          # Load address of attribute __str__
  j abort                                  # Abort

.globl error.OOB
error.OOB:
  li a0, 3                                 # Exit code for: Index out of bounds
  la a1, const_10                          # Load error message as str
  addi a1, a1, 16                          # Load address of attribute __str__
  j abort                                  # Abort

.data

.globl const_0
const_0:
  .word 2                                  # Type tag for class: bool
  .word 4                                  # Object size
  .word $bool$dispatchTable                # Pointer to dispatch table
  .word 0                                  # Constant value of attribute: __bool__
  .align 2

.globl const_1
const_1:
  .word 2                                  # Type tag for class: bool
  .word 4                                  # Object size
  .word $bool$dispatchTable                # Pointer to dispatch table
  .word 1                                  # Constant value of attribute: __bool__
  .align 2

.globl const_3
const_3:
  .word 3                                  # Type tag for class: str
  .word 8                                  # Object size
  .word $str$dispatchTable                 # Pointer to dispatch table
  .word 15                                 # Constant value of attribute: __len__
  .string "Item not found."                # Constant value of attribute: __str__
  .align 2

.globl const_9
const_9:
  .word 3                                  # Type tag for class: str
  .word 9                                  # Object size
  .word $str$dispatchTable                 # Pointer to dispatch table
  .word 16                                 # Constant value of attribute: __len__
  .string "Division by zero"               # Constant value of attribute: __str__
  .align 2

.globl const_7
const_7:
  .word 3                                  # Type tag for class: str
  .word 8                                  # Object size
  .word $str$dispatchTable                 # Pointer to dispatch table
  .word 13                                 # Constant value of attribute: __len__
  .string "Out of memory"                  # Constant value of attribute: __str__
  .align 2

.globl const_10
const_10:
  .word 3                                  # Type tag for class: str
  .word 9                                  # Object size
  .word $str$dispatchTable                 # Pointer to dispatch table
  .word 19                                 # Constant value of attribute: __len__
  .string "Index out of bounds"            # Constant value of attribute: __str__
  .align 2

.globl const_5
const_5:
  .word 3                                  # Type tag for class: str
  .word 6                                  # Object size
  .word $str$dispatchTable                 # Pointer to dispatch table
  .word 4                                  # Constant value of attribute: __len__
  .string "True"                           # Constant value of attribute: __str__
  .align 2

.globl const_8
const_8:
  .word 3                                  # Type tag for class: str
  .word 9                                  # Object size
  .word $str$dispatchTable                 # Pointer to dispatch table
  .word 17                                 # Constant value of attribute: __len__
  .string "Operation on None"              # Constant value of attribute: __str__
  .align 2

.globl const_2
const_2:
  .word 3                                  # Type tag for class: str
  .word 7                                  # Object size
  .word $str$dispatchTable                 # Pointer to dispatch table
  .word 11                                 # Constant value of attribute: __len__
  .string "Item found!"                    # Constant value of attribute: __str__
  .align 2

.globl const_4
const_4:
  .word 3                                  # Type tag for class: str
  .word 9                                  # Object size
  .word $str$dispatchTable                 # Pointer to dispatch table
  .word 16                                 # Constant value of attribute: __len__
  .string "Invalid argument"               # Constant value of attribute: __str__
  .align 2

.globl const_6
const_6:
  .word 3                                  # Type tag for class: str
  .word 6                                  # Object size
  .word $str$dispatchTable                 # Pointer to dispatch table
  .word 5                                  # Constant value of attribute: __len__
  .string "False"                          # Constant value of attribute: __str__
  .align 2

Exit environmental call gives wrong exit code.

According to the wiki, the exit environmental call should exit the program (exit status should be 0).
However, the following code:

addi a0, x0, 1
addi a1, x0, 42
ecall
addi a0, x0, 10
addi a1, x0, 100
ecall

gives exit code 100 (which is value in a1). I don't think this is correct.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.