92 lines
3.1 KiB
Scheme
92 lines
3.1 KiB
Scheme
![]() |
;;; GNU Mes --- Maxwell Equations of Software
|
||
|
;;; Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||
|
;;;
|
||
|
;;; This file is part of GNU Mes.
|
||
|
;;;
|
||
|
;;; GNU Mes 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.
|
||
|
;;;
|
||
|
;;; GNU Mes 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 GNU Mes. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
;;; Commentary:
|
||
|
|
||
|
;;; Define x86_64 M1 assembly
|
||
|
|
||
|
;;; Code:
|
||
|
|
||
|
(define-module (mescc x86_64 as)
|
||
|
#:use-module (mes guile)
|
||
|
#:use-module (mescc as)
|
||
|
#:use-module (mescc info)
|
||
|
#:export (
|
||
|
x86_64:instructions
|
||
|
))
|
||
|
|
||
|
(define (x86_64:function-preamble . rest)
|
||
|
'(("push___%rbp")
|
||
|
("mov____%rsp,%rbp")
|
||
|
;;("mov____%rdi,0x8(%rbp)" "!-0x08")
|
||
|
;;("mov____%rsi,0x8(%rbp)" "!-0x10")
|
||
|
;;("mov____%rdx,0x8(%rbp)" "!-0x18")
|
||
|
;;("mov____%rcx,0x8(%rbp)" "!-0x20")
|
||
|
))
|
||
|
|
||
|
(define (x86_64:function-locals . rest)
|
||
|
`(
|
||
|
;; FIXME: how on x86_64?
|
||
|
("sub____$i32,%rsp" (#:immediate ,(+ (* 4 1025) (* 20 8))))
|
||
|
)) ; 4*1024 buf, 20 local vars
|
||
|
|
||
|
(define (x86_64:r0->local info n)
|
||
|
(or n (error "invalid value: x86_64:r0->local: " n))
|
||
|
(let ((r0 (car (if (pair? (.allocated info)) (.allocated info) (.registers info))))
|
||
|
(n (- 0 (* 8 n))))
|
||
|
`(,(if (< (abs n) #x80) `(,(string-append "mov____%" r0 ",0x8(%rbp)") (#:immediate1 ,n))
|
||
|
`(,(string-append "mov____%" r0 ",0x32(%rbp)") (#:immediate ,n))))))
|
||
|
|
||
|
(define (x86_64:value->r0 info v)
|
||
|
(or v (error "invalid value: x86_64:value->r0: " v))
|
||
|
(let ((r0 (car (if (pair? (.allocated info)) (.allocated info) (.registers info)))))
|
||
|
`((,(string-append "mov____$i32,%" r0) (#:immediate ,v)))))
|
||
|
|
||
|
(define (x86_64:ret . rest)
|
||
|
'(("mov____%rbp,%rsp")
|
||
|
("pop____%rbp")
|
||
|
("ret")))
|
||
|
|
||
|
(define (x86_64:r0-zero? info)
|
||
|
(let ((r0 (car (if (pair? (.allocated info)) (.allocated info) (.registers info)))))
|
||
|
`((,(string-append "test___%" r0 "," "%" r0)))))
|
||
|
|
||
|
(define (x86_64:local->r0 info n)
|
||
|
(or n (error "invalid value: x86_64:local->r0: " n))
|
||
|
(let ((r0 (car (if (pair? (.allocated info)) (.allocated info) (.registers info))))
|
||
|
(n (- 0 (* 8 n))))
|
||
|
`(,(if (< (abs n) #x80) `(,(string-append "mov____0x8(%rbp),%" r0) (#:immediate1 ,n))
|
||
|
`(,(string-append "mov____0x32(%rbp),%" r0) (#:immediate ,n))))))
|
||
|
|
||
|
(define (x86_64:call-label info label n)
|
||
|
`((call32 (#:offset ,label))
|
||
|
;;("add____$i8,%esp" (#:immediate1 ,(* n 4)))
|
||
|
))
|
||
|
|
||
|
(define x86_64:instructions
|
||
|
`(
|
||
|
(call-label . ,x86_64:call-label)
|
||
|
(function-preamble . ,x86_64:function-preamble)
|
||
|
(function-locals . ,x86_64:function-locals)
|
||
|
(local->r0 . ,x86_64:local->r0)
|
||
|
(r0->local . ,x86_64:r0->local)
|
||
|
(r0-zero? . ,x86_64:r0-zero?)
|
||
|
(ret . ,x86_64:ret)
|
||
|
(value->r0 . ,x86_64:value->r0)
|
||
|
))
|