The ongoing adventures of overcomplicated makefile land.
David is dictating this commit message by the way,
PS:
They are i686 and only g++0x from before 0x
Tune in next week for another exciting episode (or installment, you, the
viewer, decide!) of randomly ifdefing things out! Will our heroes
successfully defeat the 32 bit long? Or will they perish in an integer
overflow?
(I think the project is beginning to affect our minds)
OBJ = log.o real.o bezier.o document.o objectrenderer.o view.o screen.o vfpu.o quadtree.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 div_digits_asm.o arbint.o
LIB_x86_64 = ../contrib/lib/libSDL2-2.0.so.0 -lGL -lgmp
LIB_i386 = ../contrib/lib32/libSDL2-2.0.so.0 -lGL -lgmp
+LIB_i686 = $(LIB_i386)
MAINRPATH_x86_64 = -Wl,-rpath,'$$ORIGIN/../contrib/lib'
MAINRPATH_i386 = -Wl,-rpath,'$$ORIGIN/../contrib/lib32'
+MAINRPATH_i686 = $(MAINRPATH_i386)
TESTRPATH_x86_64 = -Wl,-rpath,'$$ORIGIN/../../contrib/lib'
TESTRPATH_i386 = -Wl,-rpath,'$$ORIGIN/../../contrib/lib32'
+TESTRPATH_i686 = $(TESTRPATH_i386)
OBJPATHS = $(OBJ:%=../obj/%)
DEPS := $(OBJPATHS:%.o=%.d)
CFLAGS_x86_64 := -I../contrib/include/SDL2 -I`pwd`
CFLAGS_i386 := -I../contrib/include32/SDL2 -I`pwd`
+CFLAGS_i686 := $(CFLAGS_i386)
LIB := $(LIB_$(ARCH))
# To change that you can run as `make DEFS="REAL=X" tests/<target>` where X is your chosen type
# But remember to make clean first.
tests/% : tests/%.cpp ../obj/tests/%.o $(LINKOBJ)
-include $(DEPS)
$(BIN) : $(LINKOBJ) ../obj/$(MAIN)
echo $(LINKOBJ)
@mkdir -p $(dir $@)
- $(CXX) -o $(BIN) $(LINKOBJ) ../obj/$(MAIN) $(LIB) $(MAINRPATH)
+ $(CXX) $(CFLAGS) -o $(BIN) $(LINKOBJ) ../obj/$(MAIN) $(LIB) $(MAINRPATH)
-include $(DEPS)
@mkdir -p $(dir $@)
$(CXX) $(CFLAGS) $(DEF) -c -MMD -o $@ $<
-../obj/%_asm.o : %_asm.s main.h
+../obj/%_asm.o : %_asm.S main.h
@mkdir -p $(dir $@)
$(CXX) -c -o $@ $<
--- /dev/null
+.section .text
+.globl add_digits
+.type add_digits, @function
+
+#ifdef __x86_64__
+
+# Add two arrays of 64 bit digits, with carry, modifying the first argument
+# Address at first argument %rdi is array to add and modify
+# Address at second %rsi will be added (not modified)
+# Third argument is counter of number of digits
+# Result in %rax is the final result in the carry flag
+# Exploits the fact that inc and dec do not affect the carry flag
+add_digits:
+ addq $0, %rax
+ loop:
+ movq (%rsi), %rax # Temporarily store digit from second array
+ adcq %rax, (%rdi) # Add digits in second and first array, store in first
+ dec %rdx # Decrement counter
+ jz end_loop # We are done
+
+ # Move to next element in the first array
+ leaq 8(,%rdi,1), %rdi
+ # Move to next element in the second array
+ leaq 8(,%rsi,1), %rsi
+ jmp loop # Repeat
+ end_loop:
+ movq $0, %rax
+ jnc end
+ movq $1, %rax
+ end:
+ ret # We are done
+
+#else
+
+add_digits:
+ ret
+
+#endif
+++ /dev/null
-.section .text
-.globl add_digits
-.type add_digits, @function
-
-# Add two arrays of 64 bit digits, with carry, modifying the first argument
-# Address at first argument %rdi is array to add and modify
-# Address at second %rsi will be added (not modified)
-# Third argument is counter of number of digits
-# Result in %rax is the final result in the carry flag
-# Exploits the fact that inc and dec do not affect the carry flag
-add_digits:
- addq $0, %rax
- loop:
- movq (%rsi), %rax # Temporarily store digit from second array
- adcq %rax, (%rdi) # Add digits in second and first array, store in first
- dec %rdx # Decrement counter
- jz end_loop # We are done
-
- # Move to next element in the first array
- leaq 8(,%rdi,1), %rdi
- # Move to next element in the second array
- leaq 8(,%rsi,1), %rsi
- jmp loop # Repeat
- end_loop:
- movq $0, %rax
- jnc end
- movq $1, %rax
- end:
- ret # We are done
int64_t AsDigit() const
{
- int64_t digit = (m_digits.size() == 1) ? m_digits[0] : 0x7FFFFFFFFFFFFFFF;
+ int64_t digit = (m_digits.size() == 1) ? m_digits[0] : 0xBADF00D;
return (m_sign) ? -digit : digit;
}
--- /dev/null
+.section .text
+.globl div_digits
+.type div_digits, @function
+
+#ifdef __x86_64__
+
+# div_digits(digits, div, size, res)
+# divides an arbint in digits by uint64 div into res, returns remainder
+# res may alias digits
+# digits = rdi, div = rsx, size = rdx, res = rcx,
+div_digits:
+ movq %rdx, %r8
+ leaq -8(%rdi,%r8,8), %rdi # We want to point to the end of the buffer (LSB)
+ leaq -8(%rcx,%r8,8), %rcx # We want to point to the end of the buffer (LSB)
+ movq $0, %rdx
+loop:
+ movq (%rdi), %rax
+ divq %rsi # rdx:rax/rsi => rax, rdx:rax%rsi => rdx
+ movq %rax, (%rcx)
+ dec %r8
+ leaq -8(%rdi), %rdi
+ leaq -8(%rcx), %rcx
+ jnz loop
+end:
+ movq %rdx, %rax # return the remainder
+ ret
+
+#else
+
+div_digits:
+ ret
+
+#endif
+++ /dev/null
-.section .text
-.globl div_digits
-.type div_digits, @function
-
-# div_digits(digits, div, size, res)
-# divides an arbint in digits by uint64 div into res, returns remainder
-# res may alias digits
-# digits = rdi, div = rsx, size = rdx, res = rcx,
-div_digits:
- movq %rdx, %r8
- leaq -8(%rdi,%r8,8), %rdi # We want to point to the end of the buffer (LSB)
- leaq -8(%rcx,%r8,8), %rcx # We want to point to the end of the buffer (LSB)
- movq $0, %rdx
-loop:
- movq (%rdi), %rax
- divq %rsi # rdx:rax/rsi => rax, rdx:rax%rsi => rdx
- movq %rax, (%rcx)
- dec %r8
- leaq -8(%rdi), %rdi
- leaq -8(%rcx), %rcx
- jnz loop
-end:
- movq %rdx, %rax # return the remainder
- ret
-
-
#ifndef _FRAMEBUFFER_H
#define _FRAMEBUFFER_H
-#include <SDL.h>
+#include "SDL.h"
#include "gl_core44.h"
#ifndef _GRAPHICSBUFFER_H
#define _GRAPHICSBUFFER_H
-#include <SDL.h>
+#include "SDL.h"
#include "gl_core44.h"
total_real_time += real_frame; total_cpu_time += cpu_frame; total_gpu_time += gpu_frame;
if (data_rate > 0 && total_real_time > data_rate*(data_points+1))
{
- printf("%lu\t%f\t%f\t%f\t%f\t%f\t%f\n", (uint64_t)frames, total_real_time, total_cpu_time, total_gpu_time, real_frame, cpu_frame, gpu_frame);
+ printf("%lu\t%f\t%f\t%f\t%f\t%f\t%f\n", (long unsigned int)frames, total_real_time, total_cpu_time, total_gpu_time, real_frame, cpu_frame, gpu_frame);
data_points++;
}
scr.DebugFontPrintF("Rendered frame %lu\n", (uint64_t)frames);
--- /dev/null
+.section .text
+.globl mul_digits
+.type mul_digits, @function
+
+#ifdef __x86_64__
+
+# 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
+
+#else
+
+mul_digits:
+ ret
+
+#endif
+++ /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
if (m_indexes[i] < first_obj_id) continue;
if (m_indexes[i] >= last_obj_id) continue;
PixelBounds bounds(CPURenderBounds(objects.bounds[m_indexes[i]], view, target));
- for (int64_t x = max(0L, bounds.x); x <= min(bounds.x+bounds.w, target.w-1); ++x)
+ for (int64_t x = max((int64_t)0, bounds.x); x <= min(bounds.x+bounds.w, target.w-1); ++x)
{
- for (int64_t y = max(0L, bounds.y); y <= min(bounds.y+bounds.h, target.h-1); ++y)
+ for (int64_t y = max((int64_t)0, bounds.y); y <= min(bounds.y+bounds.h, target.h-1); ++y)
{
int index = (x+target.w*y)*4;
target.pixels[index+0] = 0;
//Debug("Centre is %d, %d", centre_x, centre_y);
//Debug("Bounds are %d,%d,%d,%d", bounds.x, bounds.y, bounds.w, bounds.h);
//Debug("Windos is %d,%d", target.w, target.h);
- for (int64_t x = max(0L, bounds.x); x <= min(bounds.x+bounds.w, target.w-1); ++x)
+ for (int64_t x = max((int64_t)0, bounds.x); x <= min(bounds.x+bounds.w, target.w-1); ++x)
{
- for (int64_t y = max(0L, bounds.y); y <= min(bounds.y + bounds.h, target.h-1); ++y)
+ for (int64_t y = max((int64_t)0, bounds.y); y <= min(bounds.y + bounds.h, target.h-1); ++y)
{
Real dx(2); dx *= Real(x - centre_x)/Real(bounds.w);
Real dy(2); dy *= Real(y - centre_y)/Real(bounds.h);
Real x[2]; Real y[2];
control.Evaluate(x[0], y[0], Real(0));
- int64_t blen = max(2L, min(100L, pix_bounds.w));
+ int64_t blen = max((int64_t)2, min((int64_t)100, pix_bounds.w));
Real invblen(1); invblen /= blen;
Debug("Using %li lines, inverse %f", blen, Double(invblen));
for (int64_t j = 1; j <= blen; ++j)
#elif REAL == REAL_LONG_DOUBLE
typedef long double Real;
#elif REAL == REAL_VFPU
- typedef VFPU::Float Real;
+ typedef VFPU::VFloat Real;
inline float Float(const Real & r) {return r.m_value;}
inline double Double(const Real & r) {return r.m_value;}
#elif REAL == REAL_RATIONAL
#ifndef _SCREEN_H
#define _SCREEN_H
-#include <SDL.h>
+#include "SDL.h"
#include <functional>
--- /dev/null
+.section .text
+.globl sub_digits
+.type sub_digits, @function
+
+#ifdef __x86_64__
+
+# Subtract two arrays of 64 bit digits, with carry, modifying the first argument
+# Address at first argument %rdi is array to add and modify
+# Address at second %rsi will be added (not modified)
+# Third argument is counter of number of digits
+# Result in %rax is the final result in the carry flag
+# Exploits the fact that inc and dec do not affect the carry flag
+sub_digits:
+ subq $0, %rax # Reset the carry/borrow flag
+ loop:
+ movq (%rsi), %rax # Temporarily store digit from second array
+ sbbq %rax, (%rdi) # Subtract digits in second and first array, store in first
+ dec %rdx # Decrement counter
+ jz end_loop # We are done
+
+ # Move to next element in the first array
+ leaq 8(,%rdi,1), %rdi
+ # Move to next element in the second array
+ leaq 8(,%rsi,1), %rsi
+ jmp loop # Repeat
+ end_loop:
+ movq $0, %rax
+ jnc end
+ movq $1, %rax
+ end:
+ ret # We are done
+
+#else
+
+sub_digits:
+ ret
+
+#endif
+++ /dev/null
-.section .text
-.globl sub_digits
-.type sub_digits, @function
-
-# Subtract two arrays of 64 bit digits, with carry, modifying the first argument
-# Address at first argument %rdi is array to add and modify
-# Address at second %rsi will be added (not modified)
-# Third argument is counter of number of digits
-# Result in %rax is the final result in the carry flag
-# Exploits the fact that inc and dec do not affect the carry flag
-sub_digits:
- subq $0, %rax # Reset the carry/borrow flag
- loop:
- movq (%rsi), %rax # Temporarily store digit from second array
- sbbq %rax, (%rdi) # Subtract digits in second and first array, store in first
- dec %rdx # Decrement counter
- jz end_loop # We are done
-
- # Move to next element in the first array
- leaq 8(,%rdi,1), %rdi
- # Move to next element in the second array
- leaq 8(,%rsi,1), %rsi
- jmp loop # Repeat
- end_loop:
- movq $0, %rax
- jnc end
- movq $1, %rax
- end:
- ret # We are done
{
assert(g_running);
stringstream s;
- //TODO: Make it compile on non C++11
- s << hex << setw(8) << setfill('0') << a.to_ullong() << "\n" << b.to_ullong() << "\n" << setw(1) << op <<"\n" << setw(1) << rmode << "\n";
+ s << hex << setw(8) << setfill('0') << a.to_ulong() << "\n" << b.to_ulong() << "\n" << setw(1) << op <<"\n" << setw(1) << rmode << "\n";
string str(s.str());
//Debug("Writing: %s", str.c_str());
stringstream s2;
//TODO: Make it compile on non C++11
- s2 << hex << result.to_ullong();
+ s2 << hex << result.to_ulong();
//Debug("Result is: %s", s2.str().c_str());
return result;
}
/**
* Wrapper class for floats where operations are done on the VFPU
*/
- class Float
+ class VFloat
{
public:
- Float(float f = 0) : m_value(f)
+ VFloat(float f = 0) : m_value(f)
{
static bool init = false;
if (!init)
VFPU::Start("flops.vcd");
}
}
- Float(const Float & cpy) : m_value(cpy.m_value) {}
- virtual ~Float()
+ VFloat(const VFloat & cpy) : m_value(cpy.m_value) {}
+ virtual ~VFloat()
{
}
- Float & operator+=(const Float & op)
+ VFloat & operator+=(const VFloat & op)
{
m_value = Exec(m_value, op.m_value, ADD);
return *this;
}
- Float & operator-=(const Float & op)
+ VFloat & operator-=(const VFloat & op)
{
m_value = Exec(m_value, op.m_value, SUB);
return *this;
}
- Float & operator*=(const Float & op)
+ VFloat & operator*=(const VFloat & op)
{
m_value = Exec(m_value, op.m_value, MULT);
return *this;
}
- Float & operator/=(const Float & op)
+ VFloat & operator/=(const VFloat & op)
{
m_value = Exec(m_value, op.m_value, DIV);
return *this;
}
- Float operator+(const Float & op) const {Float f(*this); f+=op; return f;}
- Float operator-(const Float & op) const {Float f(*this); f-=op; return f;}
- Float operator*(const Float & op) const {Float f(*this); f*=op; return f;}
- Float operator/(const Float & op) const {Float f(*this); f/=op; return f;}
+ VFloat operator+(const VFloat & op) const {VFloat f(*this); f+=op; return f;}
+ VFloat operator-(const VFloat & op) const {VFloat f(*this); f-=op; return f;}
+ VFloat operator*(const VFloat & op) const {VFloat f(*this); f*=op; return f;}
+ VFloat operator/(const VFloat & op) const {VFloat f(*this); f/=op; return f;}
- bool operator==(const Float & op) const
+ bool operator==(const VFloat & op) const
{
- Float f(op);
+ VFloat f(op);
f -= *this;
return (f.m_value == 0);
}
- bool operator!=(const Float & op) const {return !this->operator==(op);}
- bool operator<(const Float & op) const
+ bool operator!=(const VFloat & op) const {return !this->operator==(op);}
+ bool operator<(const VFloat & op) const
{
- Float f(op);
+ VFloat f(op);
f -= *this;
return (f.m_value > 0);
}
- bool operator<=(const Float & op) const
+ bool operator<=(const VFloat & op) const
{
- Float f(op);
+ VFloat f(op);
f -= *this;
return (f.m_value >= 0);
}
- bool operator>(const Float & op) const {return !this->operator<=(op);}
- bool operator>=(const Float & op) const {return !this->operator<(op);}
+ bool operator>(const VFloat & op) const {return !this->operator<=(op);}
+ bool operator>=(const VFloat & op) const {return !this->operator<(op);}
float m_value;