Just does the multiplication of the array by one digit, taking into account overflows.
I hope. It's kind of difficult to test.
What I need is a VM with equivelant instruction set but magically uses decimals instead of binary 64 bit, so I can test with numbers
that my feeble human brain understands directly...
# TODO: stb_truetype doesn't compile with some of these warnings.
CXX = g++ -std=gnu++0x -g -Wall -Werror -Wshadow -pedantic -rdynamic
MAIN = main.o
-OBJ = log.o real.o bezier.o document.o objectrenderer.o view.o screen.o vfpu.o graphicsbuffer.o framebuffer.o shaderprogram.o stb_truetype.o gl_core44.o add_digits_asm.o sub_digits_asm.o arbint.o
+OBJ = log.o real.o bezier.o document.o objectrenderer.o view.o screen.o vfpu.o graphicsbuffer.o framebuffer.o shaderprogram.o stb_truetype.o gl_core44.o add_digits_asm.o sub_digits_asm.o mul_digits_asm.o arbint.o
LIB_x86_64 = ../contrib/lib/libSDL2-2.0.so.0 -lGL
LIB_i386 = ../contrib/lib32/libSDL2-2.0.so.0 -lGL
--- /dev/null
+.section .text
+.globl mul_digits
+.type mul_digits, @function
+
+# Multiply an array of 64 bit digits by *one* 64 bit digit, modifies the array in place
+mul_digits:
+ movq %rdx, %rcx # rdx is reserved for mulq, use rcx as counter
+ movq $0, %r12 # Overflow register
+ loop:
+ movq %rsi, %rax # Value to multiply in %rax
+ mulq (%rdi) # Multiply, stored in %rdx:%rax (ie: we get TWO digits)
+
+ # Add overflow from previous operation
+ add %r12, %rax
+ # Upper digit gets saved as next overflow
+ movq %rdx, %r12
+
+ # Lower digit goes in current array position
+ movq %rax, (%rdi)
+
+ dec %rcx # Decrement counter
+ jz end_loop # We are done
+
+ # Move to next element in the array
+ leaq 8(,%rdi,1), %rdi
+ jmp loop # Repeat
+
+ end_loop:
+ end:
+ movq %r12, %rax # Return overflow
+ ret # We are done
int main(int argc, char ** argv)
{
- Arbint a(100L);
- Arbint b(200L);
+ int64_t test[] = {12L, 5L};
+ test[1] = 0xE000000000000000;
+ int64_t size = sizeof(test)/sizeof(int64_t);
- Arbint c(b-a);
- printf("(%d), %s\n",c.Sign(), c.DigitStr().c_str());
+ int64_t mul = 2L;
+
+ int64_t overflow = mul_digits(test, mul, size);
+
+ for (int64_t i = 0; i < size; ++i)
+ {
+ printf("digit[%li] = %.16lx\n", i, test[i]);
+ }
+ printf("Overflow is %.16lx\n", overflow);
}