;; AMD
(define (x86_64:function-preamble info . rest)
- (format (current-error-port) "rest=~s\n" rest)
`(("push___%rbp")
("mov____%rsp,%rbp")
("sub____$i32,%rbp" "%0x80")
;; traditional
(define (x86_64:function-preamble info . rest)
- (format (current-error-port) "rest=~s\n" rest)
`(("push___%rbp")
("mov____%rsp,%rbp")))
(define (x86_64:r->local info n)
(let ((r (get-r info))
(n (- 0 (* 8 n))))
- `(,(if (< (abs n) #x80) `(,(string-append "mov____%" r ",0x8(%rbp)") (#:immediate1 ,n))
+ `(,(if (< (abs n) #x80)
+ `(,(string-append "mov____%" r ",0x8(%rbp)") (#:immediate1 ,n))
`(,(string-append "mov____%" r ",0x32(%rbp)") (#:immediate ,n))))))
(define (x86_64:value->r info v)
(or v (error "invalid value: x86_64:value->r: " v))
(let ((r (get-r info)))
- `((,(string-append "mov____$i32,%" r) (#:immediate ,v)))))
+ (if (and (>= v 0)
+ (< v #xffffffff))
+ `((,(string-append "mov____$i32,%" r) (#:immediate ,v)))
+ `((,(string-append "mov____$i64,%" r) (#:immediate8 ,v))))))
;; AMD
(define (x86_64:ret . rest)
(define (x86_64:label->arg info label i)
(let ((r0 (list-ref x86_64:registers (1+ i))))
- `((,(string-append "mov____$i32,%" r0) (#:address ,label))))) ;; FIXME: 64 bits
+ (if (< (label v) #x80000000)
+ `((,(string-append "mov____$i32,%" r0) (#:address ,label)))
+ `((,(string-append "mov____$i64,%" r0) (#:address8 ,label))))))
;; traditional
(define (x86_64:r->arg info i)
(define (x86_64:label->arg info label i)
`(("push___$i32" (#:address ,label))))
+;; FIXME?
+;; (define (x86_64:label->arg info label i)
+;; `((,(string-append "mov____$i64,%r15") (#:address8 ,label))
+;; ("push___%r15" (#:address ,label))))
+
(define (x86_64:r0+r1 info)
(let ((r1 (get-r1 info))
(r0 (get-r0 info)))
(define (x86_64:r-mem-add info v)
(let ((r (get-r info)))
`(,(if (< (abs v) #x80) `(,(string-append "add____$i8,(%" r ")") (#:immediate1 ,v))
- `(,(string-append "add____$i32,(%" r ")") (#:immediate ,v))))))
+ `(,(string-append "add____$i32,(%" r ")") (#:immediate ,v)))))) ;; FIXME 64bit
(define (x86_64:r-byte-mem-add info v)
(let ((r (get-r info)))
(let ((n (- 0 (* 8 n))))
`((,(string-append "mov____%rbp,%" r))
,(if (< (abs n) #x80) `(,(string-append "add____$i8,%" r) (#:immediate1 ,n))
- `(,(string-append "add____$i32,%" r) (#:immediate ,n)))))))
+ `(,(string-append "add____$i32,%" r) (#:immediate ,n))))))) ;; FIXME 64bit
(define (x86_64:label->r info label)
(let ((r (get-r info)))
- `((,(string-append "mov____$i32,%" r) (#:address ,label)))))
+ `((,(string-append "mov____$i64,%" r) (#:address8 ,label)))))
(define (x86_64:r0->r1 info)
(let ((r0 (get-r0 info))
(let ((n (- 0 (* 8 n))))
`(,(if (and (< (abs n) #x80)
(< (abs v) #x80)) `("add____$i8,0x8(%rbp)" (#:immediate1 ,n) (#:immediate1 ,v))
- `("add____$i32,0x32(%rbp)" (#:immediate ,n) (#:immediate ,v))))))
+ `("add____$i32,0x32(%rbp)" (#:immediate ,n) (#:immediate ,v)))))) ;; FIXME: 64b
(define (x86_64:label-mem-add info label v)
`(,(if (< (abs v) #x80) `("add____$i8,0x32" (#:address ,label) (#:immediate1 ,v))
- `("add____$i32,0x32" (#:address ,label) (#:immediate ,v)))))
+ `("add____$i32,0x32" (#:address ,label) (#:immediate ,v))))) ;; FIXME: 64b
(define (x86_64:nop info)
'(("nop")))
(let ((r (get-r info)))
`((,(string-append "mov____%" r ",0x32") (#:address ,label))))) ;; FIXME: 64 bits
+(define (x86_64:r->byte-label info label)
+ (let* ((r (get-r info))
+ (l (r->l r)))
+ `((,(string-append "movb___%" l ",0x32") (#:address ,label)))))
+
+(define (x86_64:r->word-label info label)
+ (let* ((r (get-r info))
+ (x (r->x r)))
+ `((,(string-append "movw___%" x ",0x32") (#:address ,label)))))
+
+(define (x86_64:r->long-label info label)
+ (let* ((r (get-r info))
+ (e (r->e r)))
+ `((,(string-append "movl___%" e ",0x32") (#:address ,label)))))
+
(define (x86_64:call-r info n)
(let ((r (get-r info)))
`((,(string-append "call___*%" r))
(r1 (get-r1 info)))
`((,(string-append "and____%" r1 ",%" r0)))))
-(define (x86_64:r0/r1 info)
+(define (x86_64:r0/r1 info signed?)
(let ((allocated (.allocated info))
(r0 (get-r0 info))
(r1 (get-r1 info)))
`(,@(if (equal? r0 "rax") '()
`(("push___%rax")
(,(string-append "mov____%" r0 ",%rax"))))
- ("xor____%rdx,%rdx")
+ ,(if signed? '("cqto") '("xor____%rdx,%rdx"))
(,(string-append "idiv___%" r1))
,@(if (equal? r0 "rax") '()
`((,(string-append "mov____%rax,%" r0))
("push___%rdx")
(,(string-append "mov____%" r1 ",%rdi"))
(,(string-append "mov____%" r0 ",%rax"))
- ("xor____%rdx,%rdx")
+ ,(if signed? '("cqto") '("xor____%rdx,%rdx"))
(,(string-append "idiv___%rdi"))
("pop____%rdx")
("pop____%rdi")
(,(string-append "mov____%rax,%" r0))
("pop____%rax")))))
-(define (x86_64:r0%r1 info)
+(define (x86_64:r0%r1 info signed?)
(let ((allocated (.allocated info))
(r0 (get-r0 info))
(r1 (get-r1 info)))
`(,@(if (equal? r0 "rax") '()
`(("push___%rax")
(,(string-append "mov____%" r0 ",%rax"))))
- ("xor____%rdx,%rdx")
+ ,(if signed? '("cqto") '("xor____%rdx,%rdx"))
(,(string-append "idiv___%" r1))
(,(string-append "mov____%rdx,%" r0)))
`(("push___%rax")
("push___%rdx")
(,(string-append "mov____%" r1 ",%rdi"))
(,(string-append "mov____%" r0 ",%rax"))
- ("xor____%rdx,%rdx")
+ ,(if signed? '("cqto") '("xor____%rdx,%rdx"))
(,(string-append "idiv___%rdi"))
("pop____%rdx")
("pop____%rdi")
(define (x86_64:r+value info v)
(let ((r (get-r info)))
- `(,(if (< (abs v) #x80) `(,(string-append "add____$i8,%" r) (#:immediate1 ,v))
- `(,(string-append "add____$i32,%" r) (#:immediate ,v))))))
+ (cond ((< (abs v) #x80)
+ `((,(string-append "add____$i8,%" r) (#:immediate1 ,v))))
+ ((< (abs v) #x80000000)
+ `((,(string-append "add____$i32,%" r) (#:immediate ,v))))
+ (else
+ `((,(string-append "mov____$i64,%r15") (#:immediate8 ,v))
+ (,(string-append "add____%r15,%" r)))))))
(define (x86_64:r0->r1-mem info)
(let ((r0 (get-r0 info))
(define (x86_64:r-cmp-value info v)
(let ((r (get-r info)))
- `(,(if (< (abs v) #x80) `(,(string-append "cmp____$i8,%" r) (#:immediate1 ,v))
- `(,(string-append "cmp____$i32,%" r) (#:immediate ,v))))))
+ (cond ((< (abs v) #x80)
+ `((,(string-append "cmp____$i8,%" r) (#:immediate1 ,v))))
+ ((and (>= v 0)
+ (< v #xffffffff))
+ `((,(string-append "cmp____$i32,%" r) (#:immediate ,v))))
+ (else
+ `(,(string-append "mov____$i64,%r15") (#:immediate8 ,v)
+ ,(string-append "cmp____%r15,%" r))))))
(define (x86_64:push-register info r)
`((,(string-append "push___%" r))))
`((,(string-append "mov____(%" r0 "),%" r2))
(,(string-append "mov____%" r2 ",(%" r1 ")")))))
+(define (x86_64:byte-r0-mem->r1-mem info)
+ (let* ((registers (.registers info))
+ (r0 (get-r0 info))
+ (r1 (get-r1 info))
+ (r2 (car registers))
+ (l2 (r->l r2)))
+ `((,(string-append "mov____(%" r0 "),%" l2))
+ (,(string-append "mov____%" l2 ",(%" r1 ")")))))
+
+(define (x86_64:word-r0-mem->r1-mem info)
+ (let* ((registers (.registers info))
+ (r0 (get-r0 info))
+ (r1 (get-r1 info))
+ (r2 (car registers))
+ (x2 (r->x r2)))
+ `((,(string-append "mov____(%" r0 "),%" x2))
+ (,(string-append "mov____%" x2 ",(%" r1 ")")))))
+
+(define (x86_64:long-r0-mem->r1-mem info)
+ (let* ((registers (.registers info))
+ (r0 (get-r0 info))
+ (r1 (get-r1 info))
+ (r2 (car registers))
+ (e2 (r->e r2)))
+ `((,(string-append "mov____(%" r0 "),%" e2))
+ (,(string-append "mov____%" e2 ",(%" r1 ")")))))
+
(define (x86_64:r0+value info v)
(let ((r0 (get-r0 info)))
`(,(if (< (abs v) #x80) `(,(string-append "add____$i8,%" r0) (#:immediate1 ,v))
- `(,(string-append "add____$i32,%" r0) (#:immediate ,v))))))
+ `(,(string-append "add____$i32,%" r0) (#:immediate ,v)))))) ; FIXME: 64bit
(define (x86_64:value->r0 info v)
(let ((r0 (get-r0 info)))
(define (x86_64:r-long-mem-add info v)
(let ((r (get-r info)))
- `(,(if (< (abs v) #x80) `(,(string-append "addl___$i8,(%" r ")") (#:immediate1 ,v))
- `(,(string-append "addl___$i32,(%" r ")") (#:immediate ,v))))))
+ (cond ((< (abs v) #x80)
+ `((,(string-append "addl___$i8,(%" r ")") (#:immediate1 ,v))))
+ ((and (>= v 0)
+ (< v #xffffffff))
+ `((,(string-append "addl___$i32,(%" r ")") (#:immediate ,v))))
+ (else
+ `((,(string-append "mov____$i64,%r15") (#:immediate8 ,v))
+ (,(string-append "add____%r15,(%" r ")")))))))
(define (x86_64:byte-r->local+n info id n)
(let* ((n (+ (- 0 (* 8 id)) n))
(define (x86_64:r-and info v)
(let ((r (get-r info)))
- `((,(string-append "and____$i32,%" r) (#:immediate ,v)))))
+ (if (and (>= v 0)
+ (< v #xffffffff))
+ `((,(string-append "and____$i32,%" r) (#:immediate ,v)))
+ `((,(string-append "mov____$i64,%r15") (#:immediate8 ,v))
+ (,(string-append "and____%r15,%" r))))))
(define (x86_64:push-r0 info)
(let ((r0 (get-r0 info)))
(define x86_64:instructions
`(
- (r2->r0 . ,x86_64:r2->r0)
(a?->r . ,x86_64:a?->r)
(ae?->r . ,x86_64:ae?->r)
(b?->r . ,x86_64:b?->r)
(byte-r . ,x86_64:byte-r)
(byte-r->local+n . ,x86_64:byte-r->local+n)
(byte-r0->r1-mem . ,x86_64:byte-r0->r1-mem)
- (byte-r0->r1-mem . ,x86_64:byte-r0->r1-mem)
+ (byte-r0-mem->r1-mem . ,x86_64:byte-r0-mem->r1-mem)
(byte-signed-r . ,x86_64:byte-signed-r)
(call-label . ,x86_64:call-label)
(call-r . ,x86_64:call-r)
(long-r . ,x86_64:long-r)
(long-r->local+n . ,x86_64:long-r->local+n)
(long-r0->r1-mem . ,x86_64:long-r0->r1-mem)
+ (long-r0-mem->r1-mem . ,x86_64:long-r0-mem->r1-mem)
(long-signed-r . ,x86_64:long-signed-r)
(mem->r . ,x86_64:mem->r)
(nop . ,x86_64:nop)
(r+r . ,x86_64:r+r)
(r+value . ,x86_64:r+value)
(r->arg . ,x86_64:r->arg)
+ (r->byte-label . ,x86_64:r->byte-label)
(r->label . ,x86_64:r->label)
(r->local . ,x86_64:r->local)
(r->local+n . ,x86_64:r->local+n)
+ (r->long-label . ,x86_64:r->long-label)
+ (r->word-label . ,x86_64:r->word-label)
(r-and . ,x86_64:r-and)
(r-byte-mem-add . ,x86_64:r-byte-mem-add)
(r-cmp-value . ,x86_64:r-cmp-value)
(r0<<r1 . ,x86_64:r0<<r1)
(r0>>r1 . ,x86_64:r0>>r1)
(r1->r0 . ,x86_64:r1->r0)
+ (r2->r0 . ,x86_64:r2->r0)
(ret . ,x86_64:ret)
(return->r . ,x86_64:return->r)
(shl-r . ,x86_64:shl-r)
(word-r . ,x86_64:word-r)
(word-r->local+n . ,x86_64:word-r->local+n)
(word-r0->r1-mem . ,x86_64:word-r0->r1-mem)
+ (word-r0-mem->r1-mem . ,x86_64:word-r0-mem->r1-mem)
(word-signed-r . ,x86_64:word-signed-r)
(xor-zf . ,x86_64:xor-zf)
(zf->r . ,x86_64:zf->r)