#
#    Mecrisp-Quintus - A native code Forth implementation for RISC-V
#    Copyright (C) 2018  Matthias Koch
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# -----------------------------------------------------------------------------
insert_jalrx3: # ( Ziel Opcodelücke -- )
# -----------------------------------------------------------------------------
  push_x1_x10

  popda x10 # Opcodelücke

  dup
  # High-Part
  srli x3, x3, 16
  li x5, 0x3C050000 # lui x5, 0
  or x3, x3, x5
  pushda x10
  call kommairgendwo

  # Low-Part
  andi x3, x3, 0xFFFF
  li x5, 0x34A50000 # ori x5, x5, 0
  or x3, x3, x5
  pushda x10
  addi x3, x3, 4
  call kommairgendwo

  pushdaconst 0x00A01809 # jalr x3, x5
  pushda x10
  addi x3, x3, 8
  call kommairgendwo

  pushdaconst 0x00C63025 # or x6, x6, x6 = nop
  pushda x10
  addi x3, x3, 12
  call kommairgendwo

  pop_x1_x10
  ret

# -----------------------------------------------------------------------------
  Definition Flag_inline, "does>"
does: # Gives freshly defined word a special action.
      # Has to be used together with <builds !
# -----------------------------------------------------------------------------
    # At the place where does> is used, a jump to dodoes is inserted and
    # after that a R> to put the address of the definition entering the does>-part
    # on datastack. This is a very special implementation !

  pushdatos
  # Den Aufruf mit absoluter Adresse einkompilieren. Perform this call with absolute addressing.
  laf x5, dodoes
  jalr x3, x5

  ret # Very important as delimiter as does> itself is inline.

dodoes:
  # On the stack: ( Address-to-call R: Return-of-dodoes-itself )
  # Now insert a call into the latest definition which was hopefully prepared by <builds

  # Save and change dictionary pointer to insert a call sequence:

  push x1

  pushdaaddrf Einsprungpunkt
  lw x3, 0(x3)
  addi x3, x3, 16 # Skip pop x1 and pushdatos opcodes

  # ( Ziel Opcodelücke )
  call insert_jalrx3

  call smudge

  addi sp, sp, 4 # Skip one return layer
  pop x1
  ret

#------------------------------------------------------------------------------
  Definition Flag_visible, "<builds"
builds: # Brother of does> that creates a new definition and leaves space to insert a call instruction later.
#------------------------------------------------------------------------------
  push x1
  call create # Create new empty definition

  pushdaconst 0x2442FFFC # Write opcodes for "push x1"
  call komma
  pushdaconst 0xAC5F0000
  call komma

  pushdaconst 0x2484FFFC # Write opcodes for "pushdatos" = dup
  call komma
  pushdaconst 0xAC830000
  call komma

  pushdaconst 16 # A call instruction will go here - but I don't know its target address for now.
  call allot # Make a hole to insert the destination later.

  pop x1
  ret

#------------------------------------------------------------------------------
  Definition Flag_visible, "create" # ANS-Create with default action.
#------------------------------------------------------------------------------
  push x1
  call builds
  # Copy of the inline-code of does>
  pushdatos
  laf x5, dodoes
  jalr x3, x5
  pop x1
  ret

