Opened 9 years ago

Closed 9 years ago

#747 closed defect (fixed)

LOGIOR/LOGXOR/LOGAND and arm2-*-(un)targeted-reg-form(s) problems on ARM

Reported by: ivan4th Owned by: gb
Priority: normal Milestone:
Component: Compiler Version: trunk
Keywords: Cc:

Description

I've discovered a problem with LOGIOR/LOGXOR/LOGAND on the ARM platform when I tried to run quicklisp under CCL on my Nokia N900. The following code based on minichipz from quicklisp causes the compiler to fail due to incorrect number of arguments passed to a vinsn:

(defstruct crc32
  (crc #xffffffff :type (unsigned-byte 32)))

(defun produce-crc32 (state)
  (logxor #xffffffff (crc32-crc state)))

I've managed to fix this problem, but then ran into another problem:

Nokia-N900:/home/user# ./armcl
Welcome to Clozure Common Lisp Version 1.6-dev  (LinuxARM32)!
? (defun zzz (x y)
  (declare (type (unsigned-byte 32) x))
  (declare (type (unsigned-byte 32) y))
  (logand x y))
ZZZ
? (zzz #xffffffff #xaa)
0
? (disassemble 'zzz)
;;; (defun zzz (x y) (declare (type (unsigned-byte 32) x)) (declare (type (unsigned-byte 32) y)) (logand
  (cmp nargs (:$ 8))
  (uuo-error-wrong-nargs (:? ne))
  (mov imm0 (:$ 19))
  (stmdb (:! sp) (imm0 vsp fn lr))
  (mov fn temp2)
  (stmdb (:! vsp) (arg_z arg_y))

;;; (logand x y)
  (tst arg_z (:$ #x80000003))
  (mov imm1 (:lsr arg_z (:$ 2)))
  (beq L104)
  (and imm0 arg_z (:$ 3))
  (cmp imm0 (:$ 2))
  (uuo-error-reg-not-xtype (:? ne) arg_z (:$ 20))
  (ldr imm1 (:@ arg_z (:$ -6)))
  (movw imm0 (:$ #x107))
  (cmp imm1 imm0)
  (bne L80)
  (ldr imm1 (:@ arg_z (:$ -2)))
  (tst imm1 (:$ #x80000000))
  (uuo-error-reg-not-xtype (:? ne) arg_z (:$ 20))
  (b L104)
L80
  (add imm0 imm0 (:$ #x100))
  (cmp imm1 imm0)
  (ldreq imm0 (:@ arg_z (:$ 2)))
  (cmpeq imm0 (:$ 0))
  (ldreq imm1 (:@ arg_z (:$ -2)))
  (uuo-error-reg-not-xtype (:? ne) arg_z (:$ 20))
L104
  (mov arg_z arg_y)
  (tst arg_z (:$ #x80000003))
  (mov imm0 (:lsr arg_z (:$ 2)))
  (beq L188)
  (and imm1 arg_z (:$ 3))
  (cmp imm1 (:$ 2))
  (uuo-error-reg-not-xtype (:? ne) arg_z (:$ 20))
  (ldr imm0 (:@ arg_z (:$ -6)))
  (movw imm1 (:$ #x107))
  (cmp imm0 imm1)
  (bne L164)
  (ldr imm0 (:@ arg_z (:$ -2)))
  (tst imm0 (:$ #x80000000))
  (uuo-error-reg-not-xtype (:? ne) arg_z (:$ 20))
  (b L188)
L164
  (add imm1 imm1 (:$ #x100))
  (cmp imm0 imm1)
  (ldreq imm1 (:@ arg_z (:$ 2)))
  (cmpeq imm1 (:$ 0))
  (ldreq imm0 (:@ arg_z (:$ -2)))
  (uuo-error-reg-not-xtype (:? ne) arg_z (:$ 20))
L188
  (and imm0 imm0 imm1)
  (bla .SPmakeu32)
  (ldmia (:! sp) (imm0 vsp fn pc))

;;; #<no source text>
NIL

Here we see that the second argument is unboxed into imm1 which is reused as a temporary register when unboxing the first argument. The problem is due to the fact that when functions like ARM2-TWO-TARGETED-REG-FORMS see one of their arguments as 'const' (see e.g. aconst there) they assume that processing these arguments may not affect any registers besides directly specified. Vinsns like UNBOX-U32 though that can be generated even for such 'const' arguments may use temp registers for which 'target' registers are reused and thus become corrupted. As a workaround I've forced all *const vars in arm2-*-(un)targeted-reg-form(s) to be NIL which does solve the problem but may cause some slowdowns. Perhaps a better solution is necessary.

Attachments (1)

arm2-reg-problems.patch (8.5 KB) - added by ivan4th 9 years ago.
the patch (removed redundant comment concerning redundant LET)

Download all attachments as: .zip

Change History (3)

Changed 9 years ago by ivan4th

the patch (removed redundant comment concerning redundant LET)

comment:1 Changed 9 years ago by gb

  • Owner set to gb

comment:2 Changed 9 years ago by gb

  • Resolution set to fixed
  • Status changed from new to closed

(In [14302]) Avoid register conflicts in ARM2-TWO-TARGETED-REG-FORMS, especially when imm regs are involved and unboxing may be. (Similar functions have the same issue, but this is currently the only variant that's used to get multiple values into imm regs.)

Fix various problems in %NATURAL-LOGAND, %NATURAL-LOGIOR, %NATURAL-LOGXOR. Note that there's a little bit of asymmetry: a complemented ARM constant can be used with an AND instruction (and becomes a BIC), but there aren't variants of ORR or EOR that allow this transform.

Fixes ticket:747.

Note: See TracTickets for help on using tickets.