diff --git a/make.scm b/make.scm
index 8be7ca89..d245149d 100755
--- a/make.scm
+++ b/make.scm
@@ -166,7 +166,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
"7d-cast-char"
"7e-struct-array-access"
"7f-struct-pointer-arithmetic"
- "7g-struct-byte-word-field"))
+ "7g-struct-byte-word-field"
+ "7h-struct-assign"))
(add-target (group "check-scaffold-tests/7" #:dependencies (filter (target-prefix? "check-scaffold/tests/7") %targets)))
diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes
index bd7f914a..02e66bfc 100644
--- a/module/language/c99/compiler.mes
+++ b/module/language/c99/compiler.mes
@@ -380,16 +380,14 @@
(define (accu->ident info)
(lambda (o)
- (let ((local (assoc-ref (.locals info) o)))
- (if local (wrap-as (i386:accu->local (local:id local)))
- (let ((ptr (ident->pointer info o)))
- (list (i386:accu->label `(#:address ,o))))))))
-
-(define (base->ident info)
- (lambda (o)
- (let ((local (assoc-ref (.locals info) o)))
- (if local (wrap-as (i386:base->local (local:id local)))
- (list (i386:base->label `(#:address ,o)))))))
+ (let* ((local (assoc-ref (.locals info) o))
+ (ptr (ident->pointer info o))
+ (size (if (= ptr -1) (ident->size info o)
+ 4)))
+ (if local (if (<= size 4) (wrap-as (i386:accu->local (local:id local)))
+ (wrap-as (i386:accu*n->local (local:id local) size)))
+ (if (<= size 4) (wrap-as (i386:accu->label o))
+ (wrap-as (i386:accu*n->label o size)))))))
(define (base->ident-address info)
(lambda (o)
@@ -962,7 +960,8 @@
((equal? op "<<=") (wrap-as (i386:accu<ident info) name)))
+ ((p-expr (ident ,name))
+ (append-text info ((accu->ident info) name)))
((d-sel (ident ,field) ,p-expr)
(let* ((type (p-expr->type info p-expr))
(offset (field-offset info type field))
diff --git a/module/mes/as-i386.mes b/module/mes/as-i386.mes
index 0a94de23..3200d5ef 100644
--- a/module/mes/as-i386.mes
+++ b/module/mes/as-i386.mes
@@ -101,15 +101,18 @@
`(,(if (< (abs n) #x80) `("mov____%eax,0x8(%ebp)" (#:immediate1 ,n))
`("mov____%eax,0x32(%ebp)" (#:immediate ,n))))))
-(define (i386:base->local n)
- (or n (error "invalid value: base->local: " n))
- `(("mov____%edx,0x8(%ebp)" ,(- 0 (* 4 n))))) ; mov %edx,-<0xn>(%ebp)
-
-(define (i386:base->local n)
- (or n (error "invalid value: base->local: " n))
- (let ((n (- 0 (* 4 n))))
- `((if (< (abs n) #x80) `("mov____%edx,0x8(%ebp)" (#:immediate1 ,n))
- `("mov____%edx,0x32(%ebp)" (#:immediate ,n))))))
+(define (i386:accu*n->local i n)
+ (or n (error "invalid value: accu->local: " n))
+ (let ((o (- 0 (* 4 i))))
+ (let loop ((i 0))
+ (if (>= i n) '() ;; FIXME: byte, word-sized
+ (let ((o (+ o i)))
+ (append
+ (if (< (abs o) #x80) `(("mov____0x8(%eax),%ebx" (#:immediate1 ,i))
+ ("mov____%ebx,0x8(%ebp)" (#:immediate1 ,o)))
+ `(("mov____0x8(%eax),%ebx" (#:immediate1 ,i))
+ ("mov____%ebx,0x32(%ebp)" (#:immediate ,o))))
+ (loop (+ i 4))))))))
(define (i386:local->accu n)
(or n (error "invalid value: local->accu: " n))
@@ -223,6 +226,18 @@
(define (i386:accu->label label)
`(("mov____%eax,0x32" (#:address ,label)))) ; mov %eax,0x