-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathifunbits.ppcs
105 lines (91 loc) · 4.02 KB
/
ifunbits.ppcs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
;;; -*- Mode: LISP; Syntax: Common-Lisp; Package: ALPHA-AXP-INTERNALS; Base: 10; Lowercase: T -*-
;(include-header "aihead.s")
;(include-header "aistat.s")
;(include-header "ifunhead.s")
(comment "Bits.")
(define-instruction |DoLogand| :operand-from-stack-immediate (:own-immediate t)
(ilogical logand AND)
(immediate-handler |DoLogand|)
(ilogical-immediate logand AND))
(define-instruction |DoLogior| :operand-from-stack-immediate (:own-immediate t)
(ilogical logior OR)
(immediate-handler |DoLogior|)
(ilogical-immediate logior OR))
(define-instruction |DoLogxor| :operand-from-stack-immediate (:own-immediate t)
(ilogical logxor XOR)
(immediate-handler |DoLogxor|)
(ilogical-immediate logxor XOR))
;;; arg1 on stack = number to shift
;;; arg2 operand = shift count
(define-instruction |DoAsh| :operand-from-stack-signed-immediate ()
(stack-read2 iSP arg3 arg4 "Get ARG1.")
(srdi arg2 arg1 32 "Get ARG2's tag.")
(exts arg1 arg1 32 "Sign extended the rotation amount.")
(binary-type-dispatch (arg2 arg3 t1 t2 t3 t4)
((|TypeFixnum| |TypeFixnum|)
(branch-if-zero arg4 zerash "B. if ash of zero -- trivial case")
(branch-if-less-than-or-equal-to-zero arg1 negash "B. if negative ash.")
(exts arg4 arg4 32 "Sign extend ARG1 before shifting.")
(ADDI arg5 arg1 -32)
(branch-if-greater-than-zero arg5 ashovexc)
(SLD arg5 arg4 arg1 "Shift Left")
(XOR arg6 arg4 arg5)
(srdi arg6 arg6 31 "arg6<0>=1 if overflow, 0 otherwise")
(TagType arg2 arg2) ;strip cdr code from DTP-FIXNUM
(branch-if-nonzero arg6 ashovexc "J. if overflow")
(stack-write2 iSP arg2 arg5) ;simulate push.
(ContinueToNextInstruction)
(label negash)
(NEG arg1 arg1)
(exts arg4 arg4 32 "Sign extend ARG1 before shifting.")
(SRAD arg5 arg4 arg1 "Shift Right")
(TagType arg2 arg2) ;strip cdr code from DTP-FIXNUM
(stack-write2 iSP arg2 arg5) ;simulate push.
(ContinueToNextInstruction)
(label zerash)
(stack-write-ir |TypeFixnum| arg4 arg5)
(continueToNextInstruction))
(:else1
(clrldi arg1 arg1 32)
(SetTag arg2 arg1 t2)
(NumericTypeException arg2 ash t2))
(:else2
(clrldi arg1 arg1 32)
(SetTag arg2 arg1 t2)
(NumericTypeException arg3 ash t2)))
(label ashovexc)
(clrldi arg1 arg1 32)
(SetTag arg2 arg1 t1)
(prepare-exception ash 0 t1 arg2)
(instruction-exception))
;;; Really signed-immediate but taking low five bits eliminates the need to be careful
(define-instruction |DoRot| :operand-from-stack (:own-immediate t :needs-tos t)
(with-simple-binary-fixnum-operation (t1 t2 t3 t4 t5 t7 t8 |DoRot|)
(ANDI-DOT t2 t2 #x1F "Get low 5 bits of the rotation")
(SLD t3 t1 t2 "Shift left to get new high bits")
(srdi t6 t3 32 "Get new low bits")
(OR t3 t3 t6 "Glue two parts of shifted operand together")))
(define-instruction |DoLsh| :operand-from-stack (:own-immediate t :needs-tos t)
(with-simple-binary-fixnum-operation (t1 t2 t3 t4 t5 t7 t8 |DoLsh| nil t)
(branch-if-less-than-zero t2 neglsh "B. if negative lsh.")
;;compare to 32, if greater, result is zero
(ADDI t3 t2 -32)
(branch-if-greater-than-or-equal-to-zero t3 returnzero)
(SLD t3 t1 t2 "Shift Left")
(B lshdone)
(label neglsh)
(NEG t2 t2)
(ADDI t3 t2 -32)
(branch-if-greater-than-or-equal-to-zero T3 returnzero)
(SRD t3 t1 t2 "Shift Right")
(B lshdone)
(label returnzero)
(clr t3) ;answer is zero if (abs <shift-amount>) >= 32
(label lshdone)))
(define-instruction |Do32BitPlus| :operand-from-stack (:own-immediate t :needs-tos t)
(with-simple-binary-fixnum-operation (t1 t2 t3 t4 t5 t7 t8 |Do32BitPlus|)
(ADD t3 t1 t2 "Perform the 32 bit Add.")))
(define-instruction |Do32BitDifference| :operand-from-stack (:own-immediate t :needs-tos t)
(with-simple-binary-fixnum-operation (t1 t2 t3 t4 t5 t7 t8 |Do32BitDifference|)
(SUBF t3 t2 t1 "Perform the 32 bit Difference.")))
(comment "Fin.")