603 lines
11 KiB
Plaintext
603 lines
11 KiB
Plaintext
;
|
|
; ARM Macros file for GCC compiler
|
|
;
|
|
; Triple register is R4|R3|R2
|
|
; MUL_START. Initialise registers. Make R5 and R6 point to multipliers a
|
|
; and b. R7 points at result c.
|
|
; Initialise Triple register to 0
|
|
; See makemcs.txt for more information about this file
|
|
;
|
|
; File fixed for new GCC versions
|
|
; Hybrid method implemented - note the need to push r11 and r12 in H2_MUL_START
|
|
;
|
|
;
|
|
MACRO PMUL_START
|
|
ASM (
|
|
"MOV r5,%%0\n"
|
|
"MOV r6,%%1\n"
|
|
"MOV r7,%%2\n"
|
|
"MOV r4,%%3\n"
|
|
"MOV r3,#0\n"
|
|
"MOV r2,#0\n"
|
|
ENDM
|
|
|
|
MACRO PMUL
|
|
"LDR r0,[r5,#(4*%d)]\n"
|
|
"UMULL r8,r9,r0,r4\n"
|
|
"ADDS r8,r8,r3\n"
|
|
"ADC r3,r9,r2\n"
|
|
"STR r2,[r6,#(4*%d)]\n"
|
|
"STR r8,[r7,#(4*%d)]\n"
|
|
ENDM
|
|
|
|
MACRO PMUL_END
|
|
"UMULL r8,r9,r3,r4\n"
|
|
"STR r8,[r6]\n"
|
|
"STR r9,[r6,#4]\n"
|
|
:
|
|
:"r"(a),"r"(b),"r"(c),"r"(sn)
|
|
:"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","memory"
|
|
);
|
|
ENDM
|
|
;
|
|
; H2_MUL_START macro
|
|
; for hybrid method - process elements 2x2
|
|
;
|
|
MACRO H2_MUL_START
|
|
ASM (
|
|
"LDR r5,%%0\n"
|
|
"LDR r6,%%1\n"
|
|
"LDR r7,%%2\n"
|
|
"PUSH {r11,r12}\n"
|
|
"MOV r4,#0\n"
|
|
"MOV r3,#0\n"
|
|
"MOV r2,#0\n"
|
|
"MOV r10,#0\n"
|
|
"MOV r11,#0\n"
|
|
ENDM
|
|
|
|
MACRO H2_STEP
|
|
"LDR r8,[r5,#(4*%d)]\n"
|
|
"LDR r9,[r5,#(4*%d+4)]\n"
|
|
"LDR r12,[r6,#(4*%d)]\n"
|
|
"UMULL r0,r1,r8,r12\n"
|
|
"ADDS r2,r2,r0\n"
|
|
"ADCS r3,r3,r1\n"
|
|
"ADC r11,r11,#0\n"
|
|
"UMULL r0,r1,r9,r12\n"
|
|
"ADDS r3,r3,r0\n"
|
|
"ADCS r4,r4,r1\n"
|
|
"ADDCS r11,r11,#0x100\n"
|
|
"LDR r12,[r6,#(4*%d+4)]\n"
|
|
"UMULL r0,r1,r8,r12\n"
|
|
"ADDS r3,r3,r0\n"
|
|
"ADCS r4,r4,r1\n"
|
|
"ADDCS r11,r11,#0x100\n"
|
|
"UMULL r0,r1,r9,r12\n"
|
|
"ADDS r4,r4,r0\n"
|
|
"ADCS r10,r10,r1\n"
|
|
"ADDCS r11,r11,#0x10000\n"
|
|
ENDM
|
|
|
|
MACRO H2_LAST
|
|
"LDR r8,[r5,#(4*%d)]\n"
|
|
"LDR r9,[r5,#(4*%d+4)]\n"
|
|
"LDR r12,[r6,#(4*%d)]\n"
|
|
"UMULL r0,r1,r8,r12\n"
|
|
"ADDS r2,r2,r0\n"
|
|
"ADCS r3,r3,r1\n"
|
|
"UMULL r0,r1,r9,r12\n"
|
|
"ADD r3,r3,r0\n"
|
|
"LDR r12,[r6,#(4*%d+4)]\n"
|
|
"UMULL r0,r1,r8,r12\n"
|
|
"ADD r3,r3,r0\n"
|
|
ENDM
|
|
|
|
MACRO H2_MFIN
|
|
"STR r2,[r7,#(4*%d)]\n"
|
|
"STR r3,[r7,#(4*%d)]\n"
|
|
"AND r0,r11,#0xFF\n"
|
|
"ADDS r2,r4,r0\n"
|
|
"AND r0,r11,#0xFF00\n"
|
|
"ADCS r3,r10,r0,LSR#8\n"
|
|
"ADDCS r11,r11,#0x10000\n"
|
|
"MOV r4,r11,LSR#16\n"
|
|
"MOV r10,#0\n"
|
|
"MOV r11,#0\n"
|
|
ENDM
|
|
|
|
MACRO H2_MUL_END
|
|
"STR r2,[r7,#(4*%d)]\n"
|
|
"STR r3,[r7,#(4*%d)]\n"
|
|
"POP {r11,r12}\n"
|
|
:
|
|
:"m"(a),"m"(b),"m"(c)
|
|
:"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12","memory"
|
|
);
|
|
ENDM
|
|
|
|
MACRO MUL_START
|
|
ASM (
|
|
"MOV r5,%%0\n"
|
|
"MOV r6,%%1\n"
|
|
"MOV r7,%%2\n"
|
|
"MOV r4,#0\n"
|
|
"MOV r3,#0\n"
|
|
"MOV r2,#0\n"
|
|
ENDM
|
|
;
|
|
; STEP macro. Calculates a double-register partial product
|
|
; and adds it to the triple register total
|
|
; Parameters 1 & 2: Indices i and j for partial product multipliers a[i]
|
|
; and b[j]
|
|
|
|
MACRO STEP
|
|
"LDR r0,[r5,#(4*%d)]\n"
|
|
"LDR r1,[r6,#(4*%d)]\n"
|
|
"UMULL r8,r9,r0,r1\n"
|
|
"ADDS r2,r2,r8\n"
|
|
"ADCS r3,r3,r9\n"
|
|
"ADC r4,r4,#0\n"
|
|
ENDM
|
|
|
|
;
|
|
; MFIN macro. Finish column calculation. Store Sum for this column
|
|
; and get Carry for next
|
|
; Parameter 1: Index k for Column Sum c[k]
|
|
|
|
MACRO MFIN
|
|
"STR r2,[r7,#(4*%d)]\n"
|
|
"MOV r2,r3\n"
|
|
"MOV r3,r4\n"
|
|
"MOV r4,#0\n"
|
|
ENDM
|
|
;
|
|
; LAST
|
|
;
|
|
MACRO LAST
|
|
"LDR r0,[r5,#(4*%d)]\n"
|
|
"LDR r1,[r6,#(4*%d)]\n"
|
|
"MLA r2,r0,r1,r2\n"
|
|
ENDM
|
|
;
|
|
; MUL_END
|
|
; Parameter 1: Index for final carry c[.]
|
|
MACRO MUL_END
|
|
"STR r2,[r7,#(4*%d)]\n"
|
|
:
|
|
:"r"(a),"r"(b),"r"(c)
|
|
:"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","memory"
|
|
);
|
|
ENDM
|
|
|
|
MACRO H2_SQR_START
|
|
ASM (
|
|
"LDR r5,%%0\n"
|
|
"LDR r7,%%1\n"
|
|
"PUSH {r11,r12}\n"
|
|
"MOV r4,#0\n"
|
|
"MOV r3,#0\n"
|
|
"MOV r2,#0\n"
|
|
"MOV r10,#0\n"
|
|
"MOV r11,#0\n"
|
|
ENDM
|
|
|
|
MACRO H2_DSTEP
|
|
"LDR r8,[r5,#(4*%d)]\n"
|
|
"LDR r9,[r5,#(4*%d+4)]\n"
|
|
"LDR r12,[r5,#(4*%d)]\n"
|
|
"UMULL r0,r1,r8,r12\n"
|
|
"ADDS r2,r2,r0\n"
|
|
"ADCS r3,r3,r1\n"
|
|
"ADC r11,r11,#0\n"
|
|
"ADDS r2,r2,r0\n"
|
|
"ADCS r3,r3,r1\n"
|
|
"ADC r11,r11,#0\n"
|
|
"UMULL r0,r1,r9,r12\n"
|
|
"ADDS r3,r3,r0\n"
|
|
"ADCS r4,r4,r1\n"
|
|
"ADDCS r11,r11,#0x100\n"
|
|
"ADDS r3,r3,r0\n"
|
|
"ADCS r4,r4,r1\n"
|
|
"ADDCS r11,r11,#0x100\n"
|
|
"LDR r12,[r5,#(4*%d+4)]\n"
|
|
"UMULL r0,r1,r8,r12\n"
|
|
"ADDS r3,r3,r0\n"
|
|
"ADCS r4,r4,r1\n"
|
|
"ADDCS r11,r11,#0x100\n"
|
|
"ADDS r3,r3,r0\n"
|
|
"ADCS r4,r4,r1\n"
|
|
"ADDCS r11,r11,#0x100\n"
|
|
"UMULL r0,r1,r9,r12\n"
|
|
"ADDS r4,r4,r0\n"
|
|
"ADCS r10,r10,r1\n"
|
|
"ADDCS r11,r11,#0x10000\n"
|
|
"ADDS r4,r4,r0\n"
|
|
"ADCS r10,r10,r1\n"
|
|
"ADDCS r11,r11,#0x10000\n"
|
|
ENDM
|
|
|
|
MACRO H2_SELF
|
|
"LDR r8,[r5,#(4*%d)]\n"
|
|
"LDR r9,[r5,#(4*%d+4)]\n"
|
|
"UMULL r0,r1,r8,r8\n"
|
|
"ADDS r2,r2,r0\n"
|
|
"ADCS r3,r3,r1\n"
|
|
"ADC r11,r11,#0\n"
|
|
"UMULL r0,r1,r8,r9\n"
|
|
"ADDS r3,r3,r0\n"
|
|
"ADCS r4,r4,r1\n"
|
|
"ADDCS r11,r11,#0x100\n"
|
|
"ADDS r3,r3,r0\n"
|
|
"ADCS r4,r4,r1\n"
|
|
"ADDCS r11,r11,#0x100\n"
|
|
"UMULL r0,r1,r9,r9\n"
|
|
"ADDS r4,r4,r0\n"
|
|
"ADCS r10,r10,r1\n"
|
|
"ADDCS r11,r11,#0x10000\n"
|
|
ENDM
|
|
|
|
MACRO H2_SFIN
|
|
"STR r2,[r7,#(4*%d)]\n"
|
|
"STR r3,[r7,#(4*%d)]\n"
|
|
"AND r0,r11,#0xFF\n"
|
|
"ADDS r2,r4,r0\n"
|
|
"AND r0,r11,#0xFF00\n"
|
|
"ADCS r3,r10,r0,LSR#8\n"
|
|
"ADDCS r11,r11,#0x10000\n"
|
|
"MOV r4,r11,LSR#16\n"
|
|
"MOV r10,#0\n"
|
|
"MOV r11,#0\n"
|
|
ENDM
|
|
|
|
MACRO H2_SQR_END
|
|
"STR r2,[r7,#(4*%d)]\n"
|
|
"STR r3,[r7,#(4*%d)]\n"
|
|
"POP {r11,r12}\n"
|
|
:
|
|
:"m"(a),"m"(c)
|
|
:"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12","memory"
|
|
);
|
|
ENDM
|
|
|
|
;
|
|
; SQR_START
|
|
;
|
|
MACRO SQR_START
|
|
ASM (
|
|
"MOV r5,%%0\n"
|
|
"MOV r7,%%1\n"
|
|
"MOV r4,#0\n"
|
|
"MOV r3,#0\n"
|
|
"MOV r2,#0\n"
|
|
ENDM
|
|
;
|
|
; DSTEP macro. Calculates a double-register partial product
|
|
; and add it twice to a triple register total
|
|
; Parameters 1 & 2 : Indices of partial product multipliers
|
|
MACRO DSTEP
|
|
"LDR r0,[r5,#(4*%d)]\n"
|
|
"LDR r1,[r5,#(4*%d)]\n"
|
|
"UMULL r8,r9,r0,r1\n"
|
|
"ADDS r2,r2,r8\n"
|
|
"ADCS r3,r3,r9\n"
|
|
"ADC r4,r4,#0\n"
|
|
"ADDS r2,r2,r8\n"
|
|
"ADCS r3,r3,r9\n"
|
|
"ADC r4,r4,#0\n"
|
|
ENDM
|
|
;
|
|
; SELF macro. Calculate the double-register square and
|
|
; add it to a triple register total
|
|
; Parameter 1 : Index of diagonal element
|
|
MACRO SELF
|
|
"LDR r0,[r5,#(4*%d)]\n"
|
|
"UMULL r8,r9,r0,r0\n"
|
|
"ADDS r2,r2,r8\n"
|
|
"ADCS r3,r3,r9\n"
|
|
"ADC r4,r4,#0\n"
|
|
ENDM
|
|
;
|
|
; SFIN macro. Finish column calculation for squaring. Store Sum
|
|
; and get Carry for next column.
|
|
; Parameter 1: Index of Column Sum
|
|
MACRO SFIN
|
|
"STR r2,[r7,#(4*%d)]\n"
|
|
"MOV r2,r3\n"
|
|
"MOV r3,r4\n"
|
|
"MOV r4,#0\n"
|
|
ENDM
|
|
;
|
|
; SQR_END
|
|
; Parameter 1: Index for final carry
|
|
MACRO SQR_END
|
|
"STR r2,[r7,#(4*%d)]\n"
|
|
:
|
|
:"r"(a),"r"(c)
|
|
:"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","memory"
|
|
);
|
|
ENDM
|
|
;
|
|
; REDC_START macro
|
|
;
|
|
MACRO REDC_START
|
|
ASM (
|
|
"MOV r5,%%0\n"
|
|
"MOV r6,%%1\n"
|
|
"MOV r7,%%2\n"
|
|
"MOV r4,#0\n"
|
|
"MOV r3,#0\n"
|
|
"LDR r2,[r5]\n"
|
|
ENDM
|
|
;
|
|
; RFINU macro
|
|
;
|
|
MACRO RFINU
|
|
"MUL r1,r7,r2\n"
|
|
"STR r1,[r5,#(4*%d)]\n"
|
|
"LDR r0,[r6]\n"
|
|
"UMULL r8,r9,r0,r1\n"
|
|
"ADDS r0,r2,r8\n"
|
|
"ADCS r2,r3,r9\n"
|
|
"ADC r3,r4,#0\n"
|
|
"LDR r0,[r5,#(4*(%d+1))]\n"
|
|
"ADDS r2,r2,r0\n"
|
|
"ADC r3,r3,#0\n"
|
|
"MOV r4,#0\n"
|
|
ENDM
|
|
;
|
|
; RFIND macro
|
|
;
|
|
MACRO RFIND
|
|
"STR r2,[r5,#(4*%d)]\n"
|
|
"LDR r0,[r5,#(4*(%d+1))]\n"
|
|
"ADDS r2,r3,r0\n"
|
|
"ADC r3,r4,#0\n"
|
|
"MOV r4,#0\n"
|
|
ENDM
|
|
;
|
|
; REDC_END
|
|
;
|
|
MACRO REDC_END
|
|
"STR r2,[r5,#(4*%d)]\n"
|
|
"STR r3,[r5,#(4*(%d+1))]\n"
|
|
:
|
|
:"r"(a),"r"(b),"r"(ndash)
|
|
:"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","memory"
|
|
);
|
|
ENDM
|
|
;
|
|
; ADD_START macro - initialise for add/subtract, do first one
|
|
;
|
|
MACRO ADD_START
|
|
ASM (
|
|
"MOV r6,%%1\n"
|
|
"MOV r7,%%2\n"
|
|
"MOV r8,%%3\n"
|
|
"LDR r0,[r6]\n"
|
|
"LDR r1,[r7]\n"
|
|
"ADDS r0,r0,r1\n"
|
|
"STR r0,[r8]\n"
|
|
ENDM
|
|
;
|
|
; ADD macro. Add two numbers from memory and store result in memory.
|
|
; Don't forget carry bit
|
|
;
|
|
MACRO ADD
|
|
"LDR r0,[r6,#(4*%d)]\n"
|
|
"LDR r1,[r7,#(4*%d)]\n"
|
|
"ADCS r0,r0,r1\n"
|
|
"STR r0,[r8,#(4*%d)]\n"
|
|
ENDM
|
|
;
|
|
; ADD_END macro. Catch carry
|
|
;
|
|
MACRO ADD_END
|
|
"MOV r0,#0\n"
|
|
"MOVCS r0,#1\n"
|
|
"MOV %%0,r0\n"
|
|
:"=r"(carry)
|
|
:"r"(a),"r"(b),"r"(c)
|
|
:"r0","r1","r6","r7","r8","memory"
|
|
);
|
|
ENDM
|
|
;
|
|
; INC_START macro. Do first one
|
|
;
|
|
MACRO INC_START
|
|
ASM (
|
|
"MOV r6,%%1\n"
|
|
"MOV r7,%%2\n"
|
|
"LDR r0,[r6]\n"
|
|
"LDR r1,[r7]\n"
|
|
"ADDS r0,r0,r1\n"
|
|
"STR r0,[r6]\n"
|
|
ENDM
|
|
;
|
|
; INC macro. Add two numbers from memory and store result in memory.
|
|
; Don't forget carry bit
|
|
;
|
|
MACRO INC
|
|
"LDR r0,[r6,#(4*%d)]\n"
|
|
"LDR r1,[r7,#(4*%d)]\n"
|
|
"ADCS r0,r0,r1\n"
|
|
"STR r0,[r6,#(4*%d)]\n"
|
|
ENDM
|
|
;
|
|
; INC_END macro. Catch carry
|
|
;
|
|
MACRO INC_END
|
|
"MOV r0,#0\n"
|
|
"MOVCS r0,#1\n"
|
|
"MOV %%0,r0\n"
|
|
:"=r"(carry)
|
|
:"r"(a),"r"(b)
|
|
:"r0","r1","r6","r7","memory"
|
|
);
|
|
ENDM
|
|
;
|
|
; SUB_START macro
|
|
;
|
|
MACRO SUB_START
|
|
ASM (
|
|
"MOV r6,%%1\n"
|
|
"MOV r7,%%2\n"
|
|
"MOV r8,%%3\n"
|
|
"LDR r0,[r6]\n"
|
|
"LDR r1,[r7]\n"
|
|
"SUBS r0,r0,r1\n"
|
|
"STR r0,[r8]\n"
|
|
ENDM
|
|
;
|
|
; SUB macro. Subtract two numbers in memory and store result in memory.
|
|
;
|
|
MACRO SUB
|
|
"LDR r0,[r6,#(4*%d)]\n"
|
|
"LDR r1,[r7,#(4*%d)]\n"
|
|
"SBCS r0,r0,r1\n"
|
|
"STR r0,[r8,#(4*%d)]\n"
|
|
ENDM
|
|
;
|
|
; SUB_END macro. Catch carry
|
|
;
|
|
MACRO SUB_END
|
|
"MOV r0,#0\n"
|
|
"MOVCC r0,#1\n"
|
|
"MOV %%0,r0\n"
|
|
:"=r"(carry)
|
|
:"r"(a),"r"(b),"r"(c)
|
|
:"r0","r1","r6","r7","r8","memory"
|
|
);
|
|
ENDM
|
|
;
|
|
; DEC_START macro
|
|
;
|
|
MACRO DEC_START
|
|
ASM (
|
|
"MOV r6,%%1\n"
|
|
"MOV r7,%%2\n"
|
|
"LDR r0,[r6]\n"
|
|
"LDR r1,[r7]\n"
|
|
"SUBS r0,r0,r1\n"
|
|
"STR r0,[r6]\n"
|
|
ENDM
|
|
;
|
|
; DEC macro. Subtract two numbers in memory and store result in memory.
|
|
;
|
|
MACRO DEC
|
|
"LDR r0,[r6,#(4*%d)]\n"
|
|
"LDR r1,[r7,#(4*%d)]\n"
|
|
"SBCS r0,r0,r1\n"
|
|
"STR r0,[r6,#(4*%d)]\n"
|
|
ENDM
|
|
;
|
|
; DEC_END macro. Catch carry
|
|
;
|
|
MACRO DEC_END
|
|
"MOV r0,#0\n"
|
|
"MOVCC r0,#1\n"
|
|
"MOV %%0,r0\n"
|
|
:"=r"(carry)
|
|
:"r"(a),"r"(b)
|
|
:"r0","r1","r6","r7","memory"
|
|
);
|
|
ENDM
|
|
;
|
|
; KADD_START macro. Zero Carry flag
|
|
;
|
|
MACRO KADD_START
|
|
ASM (
|
|
"LDR r6,%%1\n"
|
|
"LDR r7,%%2\n"
|
|
"LDR r8,%%3\n"
|
|
"LDR r9,%%4\n"
|
|
"MOV r0,#0\n"
|
|
"ADDS r0,r0,r0\n"
|
|
"k%d:\n"
|
|
ENDM
|
|
;
|
|
; KASL macro. Important that carry flag is undisturbed!
|
|
;
|
|
MACRO KASL
|
|
"SUB r9,r9,#1\n"
|
|
"TEQ r9,#0\n"
|
|
"BEQ k%d\n"
|
|
"ADD r6,r6,#(4*%d)\n"
|
|
"ADD r7,r7,#(4*%d)\n"
|
|
"ADD r8,r8,#(4*%d)\n"
|
|
"B k%d\n"
|
|
"k%d:\n"
|
|
ENDM
|
|
;
|
|
; KADD_END macro
|
|
;
|
|
MACRO KADD_END
|
|
"MOV r0,#0\n"
|
|
"MOVCS r0,#1\n"
|
|
"MOV %%0,r0\n"
|
|
:"=r"(carry)
|
|
:"m"(a),"m"(b),"m"(c),"m"(n)
|
|
:"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","memory"
|
|
);
|
|
ENDM
|
|
;
|
|
; KINC_START macro. Set carry to Zero
|
|
;
|
|
MACRO KINC_START
|
|
ASM (
|
|
"LDR r6,%%1\n"
|
|
"LDR r7,%%2\n"
|
|
"LDR r9,%%3\n"
|
|
"MOV r0,#0\n"
|
|
"ADDS r0,r0,r0\n"
|
|
"k%d:\n"
|
|
ENDM
|
|
;
|
|
; KIDL macro. Important that carry flag is undisturbed!
|
|
;
|
|
MACRO KIDL
|
|
"SUB r9,r9,#1\n"
|
|
"TEQ r9,#0\n"
|
|
"BEQ k%d\n"
|
|
"ADD r6,r6,#(4*%d)\n"
|
|
"ADD r7,r7,#(4*%d)\n"
|
|
"B k%d\n"
|
|
"k%d:\n"
|
|
ENDM
|
|
;
|
|
; KINC_END macro
|
|
;
|
|
MACRO KINC_END
|
|
"MOV r0,#0\n"
|
|
"MOVCS r0,#1\n"
|
|
"MOV %%0,r0\n"
|
|
:"=r"(carry)
|
|
:"m"(a),"m"(b),"m"(n)
|
|
:"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","memory"
|
|
);
|
|
ENDM
|
|
;
|
|
; KDEC_START macro. Set carry
|
|
;
|
|
MACRO KDEC_START
|
|
ASM (
|
|
"LDR r6,%%1\n"
|
|
"LDR r7,%%2\n"
|
|
"LDR r9,%%3\n"
|
|
"SUBS r0,r0,r0\n"
|
|
"k%d:\n"
|
|
ENDM
|
|
;
|
|
; KDEC_END macro
|
|
;
|
|
MACRO KDEC_END
|
|
"MOV r0,#0\n"
|
|
"MOVCC r0,#1\n"
|
|
"MOV %%0,r0\n"
|
|
:"=r"(carry)
|
|
:"m"(a),"m"(b),"m"(n)
|
|
:"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","memory"
|
|
);
|
|
ENDM
|
|
|