⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interpreter.inc

📁 This a basic compiler for MSP430
💻 INC
📖 第 1 页 / 共 5 页
字号:
        and.w   bitpos(r14), r12             ; mask off uninteresting bits
        jz      x_false                      ; bit is zero
        jmp     x_true                       ; bit is one

bitpos:
        dw      1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7
        dw      1<<8, 1<<9, 1<<10, 1<<11, 1<<12, 1<<13, 1<<14, 1<<15

; Binary + operator
x_plus:
        add.w   r12, r14                     ; add NOS to TOS
        addc.w  r13, r15
        ret

; Binary - operator
x_minus:
        sub.w   r14, r12                     ; subtract NOS from TOS
        subc.w  r15, r13
        mov.w   r12, r14
        mov.w   r13, r15
        ret

; Binary * operator
x_star:
#ifdef   HARDWARE_MULTIPLY
        
; Save status register so we can restore IE on exit.
        push.w  sr

; Disable interrupts and really wait for them to be disabled.
        dint
        nop

; Form low product (low1 * low2).
        mov.w   r12, &MPY
        mov.w   r14, &OP2
        mov.w   r14, &MAC                    ; prepare for high1*low2 + carry-over
        mov.w   &RESLO, r14

; Carry over high part of 32-bit product to when we calculate
; the high order product.
        mov.w   &RESHI, &RESLO
        mov.w   r13, &OP2
        mov.w   r12, &MAC                    ; low1*high2 + high1*low2 + carry over
        mov.w   r15, &OP2
        mov.w   &RESLO, r15

; Restore SR and return.  Isn't the multiplier cute?
        reti

#else

; Multiplication by clockwork.  Save working registers.
        push.w  r10
        push.w  r11
         
; Clear product
        clr.w   r10
        clr.w   r11

; Single bit multiplication step
L$0     clrc
        rrc.w   r15
        rrc.w   r14
        jnc     L$1

; One bit shifted out, update product
        add.w   r12, r10
        addc.w  r13, r11

; Update shift register
L$1     add.w   r12, r12
        addc.w  r13, r13

; Continue until all bits shifted out of multiplicand.
        cmp.w   #0, r14
        jne     L$0
        cmp.w   #0, r15
        jne     L$0

; Move product to result registers.
        mov.w   r10, r14
        mov.w   r11, r15

; Restore working registers
        pop.w   r11
        pop.w   r10
        ret
#endif

; Binary / operator
x_slash:
; Exchange registers.
        xor.w   r12, r14
	xor.w   r14, r12
	xor.w   r12, r14
        xor.w   r13, r15
	xor.w   r15, r13
	xor.w   r13, r15

; Check for division by zero.
x_slash_10:
        cmp.w   #0, r13
        jnz     x_slash_20
        cmp.w   #0, r12
        jz      divide_by_zero_error

; Save working registers.
x_slash_20:
        push.w  r9
        push.w  r10
        push.w  r11

; Quotient is negative if the dividend and divisor signs differ.
        mov.w   r15, r9
        xor.w   r13, r9

; Compute magnitude of divisor.
        tst.w   r13
        jge     Positive$Divisor
        xor.w   #-1, r12
        xor.w   #-1, r13
        add.w   #1, r12
        addc.w  #0, r13

; Compute magnitude of dividend.
Positive$Divisor
        tst.w   r15
        jge     Positive$Dividend
        xor.w   #-1, r14
        xor.w   #-1, r15
        add.w   #1, r14
        addc.w  #0, r15

; Perform division, r15:r14 = quotient, r11:r10 = remainder
Positive$Dividend
        call    #___uint32_divmod

; If the dividend and divisor signs differ, negate quotient.
        tst.w   r9
        jge     Positive$Quotient
        xor.w   #-1, r14
        xor.w   #-1, r15
        add.w   #1, r14
        addc.w  #0, r15

; Restore working registers.
Positive$Quotient
        pop.w   r11
        pop.w   r10
        pop.w   r9
        ret

; Binary MOD operator
x_mod:
; Exchange arguments
        xor.w   r12, r14
	xor.w   r14, r12
	xor.w   r12, r14
        xor.w   r13, r15
	xor.w   r15, r13
	xor.w   r13, r15

; Check for division by zero.
        cmp.w   #0, r13
        jnz     x_mod_10
        cmp.w   #0, r12
        jz      divide_by_zero_error

; Save working registers.
x_mod_10:
        push.w  r11
        push.w  r10
        push.w  r9

; Sign of remainder takes sign of dividend.
        mov.w   r15, r9
        
; Compute magnitude of divisor.
        tst.w   r12
        jge     x_mod_20
        xor.w   #-1, r12
        xor.w   #-1, r13
        add.w   #1, r12
        addc.w  #0, r13

; Compute magnitude of dividend.
x_mod_20:
        tst.w   r15
        jge     x_mod_30
        xor.w   #-1, r14
        xor.w   #-1, r15
        add.w   #1, r14
        addc.w  #0, r15

; Perform division, r15:r14 = quotient, r11:r10 = remainder
x_mod_30:
        call    #___uint32_divmod

; Move remainder to result registers.
        mov.w   r10, r14
        mov.w   r11, r15

; Apply sign of dividend to remainder.
        tst.w   r9
        jge     x_mod_40
        call	#negate

; Restore working registers.
x_mod_40:
        pop.w   r9
        pop.w   r10
        pop.w   r11
        ret
        
___uint32_divmod:

; Save working registers
        push.w  r8
        push.w  r9

; Zero remainder.
        clr.w   r11
        clr.w   r10

; Prime division step count.
        mov.w   #32+1, r9
        jmp     NextStep$

; Trial subtract.
DivideStep$
        sub.w   r12, r10
        subc.w  r13, r11
        jc      NextStep$

; Trial subtraction underflowed, so restore.
        add.w   r12, r10
        addc.w  r13, r11
        clrc

; Carry contains whether subtraction was made or not (inverted).
NextStep$
        rlc.w   r14
        rlc.w   r15
        rlc.w   r10
        rlc.w   r11

; Save carry out as remainder overshoots by one bit in the last step.
        rrc.w   r8

; Iterate for 32 bits.
        dec.w   r9
        jnz     DivideStep$
        
; Restore bit shifted out of remainder.
        rlc.w   r8
        rrc.w   r11
        rrc.w   r10

; Restore working registers.
        pop.w   r9
        pop.w   r8

; Resturn with quotient in r12:r13 and remainder in r14:r15.
        ret

; AND operator
x_and:
        and.w   r12, r14
        and.w   r13, r15
        ret

; BIC operator
x_bic:
        bic.w   r14, r12
        bic.w   r15, r13
	mov.w   r12, r14
	mov.w   r13, r15
        ret

; IMP operator - a IMP b == NOT a OR b
x_imp:
        xor.w   #-1, r12
        xor.w   #-1, r13                     ; Fall through to OR

; OR operator
x_or:
        bis.w   r12, r14
        bis.w   r13, r15
        ret

; XOR operator
x_xor:
        xor.w   r12, r14
        xor.w   r13, r15
        ret

; EQV operator - a EQV b == NOT (a XOR b)
x_eqv:
        xor.w   r12, r14
        xor.w   r13, r15
	jmp     x_not_10

; NOT operator
x_not:
        call    #eval_unary                  ; evaluate argument
x_not_10:
        xor.w   #-1, r14
        xor.w   #-1, r15
        ret

; Unary - operator
x_negate:
        call    #get_eval_unary              ; evaluate argument
negate:
        xor.w   #-1, r14                     ; negate by forming one's complement
        xor.w   #-1, r15
        add.w   #1, r14                      ; and adding one to form two's complement
        addc.w  #0, r15
x_negate_return:
        ret

; VARPTR addr
x_varptr:
        call    #varptr                      ; get address
	mov.w   #0, r15                      ; overwrite size designation
	ret

; Parse a variable and return its address in R14 and zero in R15.
; The variable can be simple or an array
varptr:
        mov.w   #0, r14                      ; set the array base as zero for ?
	cmp.b   #'?', r4                     ; byte indirection operator?
        jz      varptr_25                    ; ...yes, do byte indirection
        cmp.b   #'@', r4                     ; word indirection operator?
        jnz     varptr_05
        mov.b   @tp+, r4                     ; skip '@'
        call    #eval_unary                  ; get address
        bic.w   #1, r14                      ; word align
	mov.w   #2, r15                      ; indicate 16-bit data
	ret
varptr_05:
        cmp.b   #'!', r4                     ; word indirection operator?
        jnz     varptr_07                    ; ...no, must start with a

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -