This commit is contained in:
Ingy döt Net 2013-10-27 22:24:23 +00:00
parent 6f050a029e
commit 776bba907c
3887 changed files with 59894 additions and 7280 deletions

View file

@ -0,0 +1,67 @@
import std.stdio, std.traits;
void fourBitsAdder(T)(in T a0, in T a1, in T a2, in T a3,
in T b0, in T b1, in T b2, in T b3,
out T o0, out T o1,
out T o2, out T o3,
out T overflow) pure nothrow {
// A XOR using only NOT, AND and OR, as task requires.
static T xor(in T x, in T y) pure nothrow {
return (~x & y) | (x & ~y);
}
static void halfAdder(in T a, in T b,
out T s, out T c) pure nothrow {
s = xor(a, b);
// s = a ^ b; // The built-in D xor.
c = a & b;
}
static void fullAdder(in T a, in T b, in T ic,
out T s, out T oc) pure nothrow {
T ps, pc, tc;
halfAdder(/*in*/a, b, /*out*/ps, pc);
halfAdder(/*in*/ps, ic, /*out*/s, tc);
oc = tc | pc;
}
T zero, tc0, tc1, tc2;
fullAdder(/*in*/a0, b0, zero, /*out*/o0, tc0);
fullAdder(/*in*/a1, b1, tc0, /*out*/o1, tc1);
fullAdder(/*in*/a2, b2, tc1, /*out*/o2, tc2);
fullAdder(/*in*/a3, b3, tc2, /*out*/o3, overflow);
}
void main() {
alias T = size_t;
static assert(isUnsigned!T);
enum T one = T.max,
zero = T.min,
a0 = zero, a1 = one, a2 = zero, a3 = zero,
b0 = zero, b1 = one, b2 = one, b3 = one;
T s0, s1, s2, s3, overflow;
fourBitsAdder(/*in*/ a0, a1, a2, a3,
/*in*/ b0, b1, b2, b3,
/*out*/s0, s1, s2, s3, overflow);
writefln(" a3 %032b", a3);
writefln(" a2 %032b", a2);
writefln(" a1 %032b", a1);
writefln(" a0 %032b", a0);
writefln(" +");
writefln(" b3 %032b", b3);
writefln(" b2 %032b", b2);
writefln(" b1 %032b", b1);
writefln(" b0 %032b", b0);
writefln(" =");
writefln(" s3 %032b", s3);
writefln(" s2 %032b", s2);
writefln(" s1 %032b", s1);
writefln(" s0 %032b", s0);
writefln("overflow %032b", overflow);
}

View file

@ -0,0 +1,66 @@
import std.stdio, std.traits, core.simd;
void fourBitsAdder(T)(in T a0, in T a1, in T a2, in T a3,
in T b0, in T b1, in T b2, in T b3,
out T o0, out T o1,
out T o2, out T o3,
out T overflow) pure nothrow {
// A XOR using only NOT, AND and OR, as task requires.
static T xor(in T x, in T y) pure nothrow {
return (~x & y) | (x & ~y);
}
static void halfAdder(in T a, in T b,
out T s, out T c) pure nothrow {
s = xor(a, b);
// s = a ^ b; // The built-in D xor.
c = a & b;
}
static void fullAdder(in T a, in T b, in T ic,
out T s, out T oc) pure nothrow {
T ps, pc, tc;
halfAdder(/*in*/a, b, /*out*/ps, pc);
halfAdder(/*in*/ps, ic, /*out*/s, tc);
oc = tc | pc;
}
T zero, tc0, tc1, tc2;
fullAdder(/*in*/a0, b0, zero, /*out*/o0, tc0);
fullAdder(/*in*/a1, b1, tc0, /*out*/o1, tc1);
fullAdder(/*in*/a2, b2, tc1, /*out*/o2, tc2);
fullAdder(/*in*/a3, b3, tc2, /*out*/o3, overflow);
}
int main() {
alias T = ubyte16; // ubyte32 with AVX.
immutable T zero;
immutable T one = ubyte.max;
immutable T a0 = zero, a1 = one, a2 = zero, a3 = zero,
b0 = zero, b1 = one, b2 = one, b3 = one;
T s0, s1, s2, s3, overflow;
fourBitsAdder(/*in*/ a0, a1, a2, a3,
/*in*/ b0, b1, b2, b3,
/*out*/s0, s1, s2, s3, overflow);
//writefln(" a3 %(%08b%)", a3);
writefln(" a3 %(%08b%)", a3.array);
writefln(" a2 %(%08b%)", a2.array);
writefln(" a1 %(%08b%)", a1.array);
writefln(" a0 %(%08b%)", a0.array);
writefln(" +");
writefln(" b3 %(%08b%)", b3.array);
writefln(" b2 %(%08b%)", b2.array);
writefln(" b1 %(%08b%)", b1.array);
writefln(" b0 %(%08b%)", b0.array);
writefln(" =");
writefln(" s3 %(%08b%)", s3.array);
writefln(" s2 %(%08b%)", s2.array);
writefln(" s1 %(%08b%)", s1.array);
writefln(" s0 %(%08b%)", s0.array);
writefln("overflow %(%08b%)", overflow.array);
}

View file

@ -0,0 +1,39 @@
fourBitsAdder:
pushl %ebp
movl %esp, %ebp
andl $-32, %esp
subl $32, %esp
vmovaps 136(%ebp), %ymm4
vxorps %ymm3, %ymm4, %ymm5
movl 20(%ebp), %ecx
vmovaps %ymm5, (%ecx)
vandps %ymm3, %ymm4, %ymm3
vmovaps 104(%ebp), %ymm4
vxorps %ymm2, %ymm4, %ymm5
vxorps %ymm3, %ymm5, %ymm6
movl 16(%ebp), %ecx
vmovaps %ymm6, (%ecx)
vandps %ymm3, %ymm5, %ymm3
vandps %ymm2, %ymm4, %ymm2
vorps %ymm2, %ymm3, %ymm2
vmovaps 72(%ebp), %ymm3
vxorps %ymm1, %ymm3, %ymm4
vxorps %ymm2, %ymm4, %ymm5
movl 12(%ebp), %ecx
vmovaps %ymm5, (%ecx)
vandps %ymm2, %ymm4, %ymm2
vandps %ymm1, %ymm3, %ymm1
vorps %ymm1, %ymm2, %ymm1
vmovaps 40(%ebp), %ymm2
vxorps %ymm0, %ymm2, %ymm3
vxorps %ymm1, %ymm3, %ymm4
movl 8(%ebp), %ecx
vmovaps %ymm4, (%ecx)
vandps %ymm1, %ymm3, %ymm1
vandps %ymm0, %ymm2, %ymm0
vorps %ymm0, %ymm1, %ymm0
vmovaps %ymm0, (%eax)
movl %ebp, %esp
popl %ebp
vzeroupper
ret $160

View file

@ -0,0 +1,70 @@
-module( four_bit_adder ).
-export( [add_bits/3, create/1, task/0] ).
add_bits( Adder, A_bits, B_bits ) ->
Adder ! {erlang:self(), lists:reverse(A_bits), lists:reverse(B_bits)},
receive
{Adder, Sum, Carry} -> {Sum, Carry}
end.
create( How_many_bits ) ->
Full_adders = connect_full_adders( [full_adder_create() || _X <- lists:seq(1, How_many_bits)] ),
erlang:spawn_link( fun() -> bit_adder_loop( Full_adders ) end ).
task() ->
Adder = create( 4 ),
add_bits( Adder, [0,0,1,0], [0,0,1,1] ).
bit_adder_loop( Full_adders ) ->
receive
{Pid, As, Bs} ->
Sum = [full_adder_sum(Adder, A, B) || {Adder, A, B} <- lists:zip3(Full_adders, As, Bs)],
Carry = receive
{carry, C} -> C
end,
Pid ! {erlang:self(), lists:reverse(Sum), Carry},
bit_adder_loop( Full_adders )
end.
connect_full_adders( [Full_adder | T]=Full_adders ) ->
lists:foldl( fun connect_full_adders/2, Full_adder, T ),
Full_adders.
connect_full_adders( Full_adder, Previous_full_adder ) ->
Previous_full_adder ! {carry_to, Full_adder},
Full_adder.
half_adder( A, B ) -> {z_xor(A, B), A band B}.
full_adder( A, B, Carry ) ->
{Sum1, Carry1} = half_adder( A, Carry),
{Sum, Carry2} = half_adder( B, Sum1),
{Sum, Carry1 bor Carry2}.
full_adder_create( ) -> erlang:spawn( fun() -> full_adder_loop({0, no_carry_pid}) end ).
full_adder_loop( {Carry, Carry_to} ) ->
receive
{carry, New_carry} -> full_adder_loop( {New_carry, Carry_to} );
{carry_to, Pid} -> full_adder_loop( {Carry, Pid} );
{add, Pid, A, B} ->
{Sum, New_carry} = full_adder( A, B, Carry ),
Pid ! {sum, erlang:self(), Sum},
full_adder_loop_carry_pid( Carry_to, Pid ) ! {carry, New_carry},
full_adder_loop( {New_carry, Carry_to} )
end.
full_adder_loop_carry_pid( no_carry_pid, Pid ) -> Pid;
full_adder_loop_carry_pid( Pid, _Pid ) -> Pid.
full_adder_sum( Pid, A, B ) ->
Pid ! {add, erlang:self(), A, B},
receive
{sum, Pid, S} -> S
end.
%% xor exists, this is another implementation.
z_xor( A, B ) -> (A band (2+bnot B)) bor ((2+bnot A) band B).

View file

@ -0,0 +1,12 @@
: "NOT" invert 1 and ;
: "XOR" over over "NOT" and >r swap "NOT" and r> or ;
: halfadder over over and >r "XOR" r> ;
: fulladder halfadder >r swap halfadder r> or ;
: 4bitadder ( a3 a2 a1 a0 b3 b2 b1 b0 -- r3 r2 r1 r0 c)
4 roll 0 fulladder swap >r >r
3 roll r> fulladder swap >r >r
2 roll r> fulladder swap >r fulladder r> r> r> 3 roll
;
: .add4 4bitadder 0 .r 4 0 do i 3 - abs roll 0 .r loop cr ;