From 51085ba25c7bf729a3a97a90ccba62d1e4a529a4 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sat, 6 Oct 2018 14:51:57 +0200 Subject: [PATCH] mescc: Support 64-bit immediates. * module/mescc/M1.scm (hex2:address8, hex2:immediate8): New function. (info->M1): Support 64-bit. * module/mescc/compile.scm (convert-r0): FIXME! * module/mescc/x86_64/as.scm (x86_64:value->r, x86_64:r->local, x86_64:label->arg, x86_64:label->r, x86_64:r+value, x86_64:r-cmp-value, x86_64:r-long-mem-add, x86_64:r-and): Support 64-bit immediates. * lib/x86_64-mes/x86_64.M1: Likewise. * scaffold/tests/17-compare-unsigned-char-le.c: Test it. * scaffold/tests/17-compare-unsigned-short-le.c: Test it. * build-aux/check-mescc.sh (tests): Run them. --- build-aux/check-mescc.sh | 6 ++ lib/x86_64-mes/x86_64.M1 | 22 ++++++- module/mescc/M1.scm | 37 ++++++++++- module/mescc/compile.scm | 14 +++- module/mescc/x86_64/as.scm | 64 ++++++++++++++----- module/mescc/x86_64/info.scm | 2 +- scaffold/tests/17-compare-unsigned-char-le.c | 30 +++++++++ scaffold/tests/17-compare-unsigned-long-le.c | 30 +++++++++ scaffold/tests/17-compare-unsigned-short-le.c | 30 +++++++++ scaffold/tests/a0-call-trunc-int.c | 39 +++++++++++ 10 files changed, 250 insertions(+), 24 deletions(-) create mode 100644 scaffold/tests/17-compare-unsigned-char-le.c create mode 100644 scaffold/tests/17-compare-unsigned-long-le.c create mode 100644 scaffold/tests/17-compare-unsigned-short-le.c create mode 100644 scaffold/tests/a0-call-trunc-int.c diff --git a/build-aux/check-mescc.sh b/build-aux/check-mescc.sh index 5884f8f8..e2fe6c7f 100755 --- a/build-aux/check-mescc.sh +++ b/build-aux/check-mescc.sh @@ -78,6 +78,9 @@ t 17-compare-unsigned-gt 17-compare-unsigned-le 17-compare-unsigned-lt +17-compare-unsigned-char-le +17-compare-unsigned-short-le +17-compare-unsigned-long-le 17-compare-and 17-compare-or 17-compare-and-or @@ -218,9 +221,12 @@ t 99-readdir a0-call-trunc-char a0-call-trunc-short +a0-call-trunc-int " broken="$broken +17-compare-unsigned-char-le +17-compare-unsigned-short-le 66-local-char-array " diff --git a/lib/x86_64-mes/x86_64.M1 b/lib/x86_64-mes/x86_64.M1 index 99c46402..ba80c46f 100644 --- a/lib/x86_64-mes/x86_64.M1 +++ b/lib/x86_64-mes/x86_64.M1 @@ -17,8 +17,8 @@ ### along with GNU Mes. If not, see . # reduced instruction set: rax, rdi (some rcx for shift, rdx for mul, div) -# 184 instructions -# TODO: $i64/$0x64 instructions are missing +# and r10 as i64 immediate helper +# 202 instructions DEFINE add____$i32,%rax 4805 DEFINE add____$i32,%rbp 4881c5 DEFINE add____$i32,%rdi 4881c7 @@ -30,6 +30,8 @@ DEFINE add____$i8,%rsp 4883c4 DEFINE add____$i8,(%rax) 8300 DEFINE add____$i8,(%rdi) 8307 DEFINE add____$i8,0x8(%rbp) 8345 +DEFINE add____%r15,(%rax) 4c0138 +DEFINE add____%r15,(%rdi) 4c013f DEFINE add____%rax,%rax 4801c0 DEFINE add____%rbp,%rax 4801e8 DEFINE add____%rdi,%rax 4801f8 @@ -43,12 +45,16 @@ DEFINE addl___$i8,(%rdi) 8307 DEFINE addw___$i8,(%rax) 668100 DEFINE addw___$i8,(%rdi) 668107 DEFINE and____$i32,%rdi 4881e7 +DEFINE and____%r15,%rax 4c21f8 +DEFINE and____%r15,%rdi 4c21ff DEFINE and____%rdi,%rax 4821f8 DEFINE call32 e8 DEFINE call___*%rax ffd0 DEFINE call___*%rdi ffd7 DEFINE cmp____$i32,%rax 483d DEFINE cmp____$i8,%rax 4883f8 +DEFINE cmp____%r15,%rax 4c39f8 +DEFINE cmp____%r15,%rdi 4c39ff DEFINE hlt f4 DEFINE idiv___%rdi 48f7ff DEFINE ja32 0f87 @@ -68,17 +74,24 @@ DEFINE lahf 9f DEFINE mov____$i32,%rax 48c7c0 DEFINE mov____$i32,%rdi 48c7c7 DEFINE mov____$i32,0x8(%rbp) c745 +DEFINE mov____$i64,%r15 49bf DEFINE mov____$i64,%rax 48a1 DEFINE mov____$i64,%rax 48b8 +DEFINE mov____$i64,%rax 48b8 +DEFINE mov____$i64,%rdi 48bf DEFINE mov____%al,(%rdi) 8807 DEFINE mov____%al,0x32(%rbp) 8885 DEFINE mov____%al,0x8(%rbp) 8845 DEFINE mov____%ax,(%rdi) 668907 DEFINE mov____%ax,0x8(%rbp) 668945 +DEFINE mov____%eax,%eax 89c0 +DEFINE mov____%eax,%rax 89c0 DEFINE mov____%eax,(%rdi) 8907 DEFINE mov____%eax,0x32(%rbp) 8985 DEFINE mov____%eax,0x8(%rbp) 8945 DEFINE mov____%eax,0x8(%rbp) 8945 +DEFINE mov____%edi,%edi 89ff +DEFINE mov____%edi,%rdi 89ff DEFINE mov____%edi,0x32(%rbp) 89bd DEFINE mov____%edi,0x8(%rbp) 897d DEFINE mov____%esi,%eax 89f0 @@ -145,8 +158,12 @@ DEFINE movzbq_%al,%rax 480fb6c0 DEFINE movzbq_%dil,%rdi 480fb6ff DEFINE movzbq_(%rax),%rax 480fb600 DEFINE movzbq_(%rdi),%rdi 480fb63f +DEFINE movzlq_%eax,%rax 89c0 +DEFINE movzlq_%edi,%rdi 89ff DEFINE movzlq_(%rax),%rax 8b00 DEFINE movzlq_(%rdi),%rdi 8b3f +DEFINE movzwq_%ax,%rax 480fb7c0 +DEFINE movzwq_%di,%rdi 480fb7ff DEFINE movzwq_(%rax),%rax 480fb700 DEFINE movzwq_(%rdi),%rdi 480fb73f DEFINE mul____%rdi 48f7e7 @@ -159,6 +176,7 @@ DEFINE pop____%rbp 5d DEFINE pop____%rdi 5f DEFINE pop____%rdx 5a DEFINE push___$i32 68 +DEFINE push___%r15 4157 DEFINE push___%rax 50 DEFINE push___%rbp 55 DEFINE push___%rdi 57 diff --git a/module/mescc/M1.scm b/module/mescc/M1.scm index 7ee083eb..aa76f249 100644 --- a/module/mescc/M1.scm +++ b/module/mescc/M1.scm @@ -53,6 +53,9 @@ (define (hex2:address o) (string-append "&" o)) +(define (hex2:address8 o) + (string-append "&" o " %0")) ;; FIXME: 64bit + (define (hex2:offset o) (string-append "%" o)) @@ -77,6 +80,14 @@ (if hex? (string-append "%0x" (dec->hex o)) (string-append "%" (number->string o)))) +(define (hex2:immediate8 o) + (if hex? (string-append "%0x" (dec->hex (modulo o #x100000000)) + " %0x" (if (< o 0) "-1" + (dec->hex (quotient o #x100000000)))) + (string-append "%" (number->string (dec->hex (modulo o #x100000000))) + " %" (if (< o 0) "-1" + (number->string (dec->hex (quoteint o #x100000000))))))) + (define* (display-join o #:optional (sep "")) (let loop ((o o)) (when (pair? o) @@ -110,7 +121,8 @@ ((and (pair? o) (keyword? (car o))) (pmatch o ;; FIXME - ((#:address (#:string ,string)) (hex2:address (string->label `(#:string ,string)))) + ((#:address (#:string ,string)) + (hex2:address (string->label `(#:string ,string)))) ((#:address (#:address ,address)) (guard (string? address)) (hex2:address address)) ((#:address (#:address ,global)) (guard (global? global)) @@ -119,17 +131,38 @@ (hex2:address (function->string function))) ((#:address ,number) (guard (number? number)) (string-join (map text->M1 (int->bv32 number)))) + + ((#:address8 (#:string ,string)) + (hex2:address8 (string->label `(#:string ,string)))) + ((#:address8 (#:address ,address)) (guard (string? address)) + (hex2:address8 address)) + ((#:address8 (#:address ,global)) (guard (global? global)) + (hex2:address8 (global->string global))) + ((#:address8 ,function) (guard (function? function)) + (hex2:address8 (function->string function))) + ((#:address8 ,number) (guard (number? number)) + (string-join (map text->M1 (int->bv64 number)))) + ((#:string ,string) (hex2:address (string->label o))) - ((#:address ,address) (guard (string? address)) (hex2:address address)) + + ((#:address ,address) (guard (string? address)) + (hex2:address address)) ((#:address ,global) (guard (global? global)) (hex2:address (global->string global))) + + ((#:address8 ,address) (guard (string? address)) + (hex2:address8 address)) + ((#:address8 ,global) (guard (global? global)) + (hex2:address8 (global->string global))) + ((#:offset ,offset) (hex2:offset offset)) ((#:offset1 ,offset1) (hex2:offset1 offset1)) ((#:immediate ,immediate) (hex2:immediate immediate)) ((#:immediate1 ,immediate1) (hex2:immediate1 immediate1)) ((#:immediate2 ,immediate2) (hex2:immediate2 immediate2)) ((#:immediate4 ,immediate4) (hex2:immediate4 immediate4)) + ((#:immediate8 ,immediate8) (hex2:immediate8 immediate8)) (_ (error "text->M1 no match o" o)))) ((pair? o) (string-join (map text->M1 o))))) (define (write-function o) diff --git a/module/mescc/compile.scm b/module/mescc/compile.scm index 5afbf6ec..aefa580d 100644 --- a/module/mescc/compile.scm +++ b/module/mescc/compile.scm @@ -1397,15 +1397,23 @@ (cond ((and (= size 1) sign) (wrap-as (as info 'byte-signed-r))) ((= size 1) - (wrap-as (as info 'byte-r))) + (wrap-as (as info 'byte-r)) + ;;(wrap-as (as info 'byte-signed-r)) + ) ((and (= size 2) sign) (wrap-as (as info 'word-signed-r))) ((= size 2) - (wrap-as (as info 'word-r))) + (wrap-as (as info 'word-r)) + ;;(wrap-as (as info 'word-signed-r)) + ) ((and (> reg-size 4) (= size 4) sign) (wrap-as (as info 'long-signed-r))) ((and (> reg-size 4) (= size 4)) - (wrap-as (as info 'long-signed-r))) + ;; for 17-unsigned-le + (wrap-as (as info 'long-signed-r)) ; huh, why not long-r? + ;; for a0-call-trunc-int + ;;(wrap-as (as info 'long-r)) + ) (else '()))))) (define (binop->r info) diff --git a/module/mescc/x86_64/as.scm b/module/mescc/x86_64/as.scm index 9e3f5258..ca1982a9 100644 --- a/module/mescc/x86_64/as.scm +++ b/module/mescc/x86_64/as.scm @@ -76,13 +76,17 @@ (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) @@ -122,7 +126,9 @@ (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) @@ -132,6 +138,11 @@ (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))) @@ -168,7 +179,7 @@ (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))) @@ -183,11 +194,11 @@ (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)) @@ -293,11 +304,11 @@ (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"))) @@ -460,8 +471,13 @@ (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)) @@ -488,8 +504,14 @@ (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)))) @@ -535,7 +557,7 @@ (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))) @@ -543,8 +565,14 @@ (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)) @@ -569,7 +597,11 @@ (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))) diff --git a/module/mescc/x86_64/info.scm b/module/mescc/x86_64/info.scm index dd320c88..4133ea85 100644 --- a/module/mescc/x86_64/info.scm +++ b/module/mescc/x86_64/info.scm @@ -31,7 +31,7 @@ (define (x86_64-info) (make #:types x86_64:type-alist #:registers x86_64:registers #:instructions x86_64:instructions)) -(define x86_64:registers '("rax" "rdi" "rsi" "rdx" "rcx" "r8" "r9")) +(define x86_64:registers '("rax" "rdi" "rsi" "rdx" "rcx" "r8" "r9" "r10" "r11" "r12" "r13" "r14" "r15")) (define x86_64:type-alist `(("char" . ,(make-type 'signed 1 #f)) ("short" . ,(make-type 'signed 2 #f)) diff --git a/scaffold/tests/17-compare-unsigned-char-le.c b/scaffold/tests/17-compare-unsigned-char-le.c new file mode 100644 index 00000000..24a4e6ff --- /dev/null +++ b/scaffold/tests/17-compare-unsigned-char-le.c @@ -0,0 +1,30 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * 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 . + */ + +int +main () +{ + unsigned char r = -2; + if (r <= -3) + return 1; + if (r <= (unsigned char)-1) + return 0; + return 2; +} diff --git a/scaffold/tests/17-compare-unsigned-long-le.c b/scaffold/tests/17-compare-unsigned-long-le.c new file mode 100644 index 00000000..9c34b2e7 --- /dev/null +++ b/scaffold/tests/17-compare-unsigned-long-le.c @@ -0,0 +1,30 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * 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 . + */ + +int +main () +{ + unsigned long r = -2; + if (r <= -3) + return 1; + if (r <= -1) + return 0; + return 2; +} diff --git a/scaffold/tests/17-compare-unsigned-short-le.c b/scaffold/tests/17-compare-unsigned-short-le.c new file mode 100644 index 00000000..dead66e3 --- /dev/null +++ b/scaffold/tests/17-compare-unsigned-short-le.c @@ -0,0 +1,30 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * 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 . + */ + +int +main () +{ + unsigned short r = -2; + if (r <= -3) + return 1; + if (r <= (unsigned short)-1) + return 0; + return 2; +} diff --git a/scaffold/tests/a0-call-trunc-int.c b/scaffold/tests/a0-call-trunc-int.c new file mode 100644 index 00000000..d49b385a --- /dev/null +++ b/scaffold/tests/a0-call-trunc-int.c @@ -0,0 +1,39 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * 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 . + */ + +#include + +long +f (unsigned int x) +{ + eputs ("x="); eputs (utoa (x)); eputs ("\n"); + return x; +} + +int +main () +{ + unsigned long x = -1; + x = f (x); + eputs ("x="); eputs (ultoa (x)); eputs ("\n"); + if (x != 0xffffffff) + return 1; + return 0; +}