20 x_add32(
unsigned int a2,
unsigned int a1,
unsigned int b2,
unsigned int b1,
21 unsigned int tmp1,
unsigned int tmp2,
unsigned int tmp3) {
46 x_addc(a1, b1, tmp1, tmp2, tmp3);
55 x_addc(
unsigned int a,
unsigned int b,
56 unsigned int tmp1,
unsigned int tmp2,
unsigned int tmp3) {
84 i_beq(tmp1, tmp2, addc_same_tmp1_tmp2);
90 i_beq(b, 0, addc_end);
92 i_beq(b, 0, addc_end);
94 i_beq(b, 0, addc_end);
104 x_and_to(
unsigned int result,
unsigned int a,
unsigned int b) {
130 i_beq(a1, 0, inc32_carry);
157 i_beq(result, 0, a_msb_0);
160 i_beq(result, 0, a_msb_1_b_msb_0);
170 i_beq(result, 0, must_check);
227 i_beq(tmp, 0, lshift32_end);
277 unsigned int tmp1,
unsigned int tmp2,
unsigned int tmp3) {
336 x_mov(
unsigned int result,
unsigned int a) {
348 x_mul(
unsigned int a,
unsigned int b,
349 unsigned int tmp1,
unsigned int tmp2,
unsigned int tmp3,
350 unsigned int tmp4,
unsigned int tmp5) {
380 i_beq(a, 0, mul_end);
381 i_beq(b, 0, mul_end);
414 i_beq(tmp4, 0, mul_endif_bit);
422 x_add32(tmp2, tmp1, b, a, tmp4, tmp3, tmp5);
433 i_beq(tmp5, 0, mul_end);
439 i_beq(0, 0, mul_loop);
449 unsigned int tmp1,
unsigned int tmp2,
unsigned int tmp3,
450 unsigned int tmp4,
unsigned int tmp5) {
512 x_addc(tmp1, tmp2, tmp3, tmp4, tmp5);
515 i_beq(tmp2, 0, karatsuba_not_carry);
523 x_add32(b, a, tmp2, tmp1, tmp3, tmp4, tmp5);
531 i_beq(tmp1, 0, karatsuba_diffa_pos);
541 i_beq(tmp3, 0, karatsuba_diffb_pos);
555 i_beq(tmp4, tmp5, karatsuba_diff_same_sign);
557 karatsuba_diff_same_sign:
565 x_add32(b, a, tmp2, tmp1, tmp3, tmp4, tmp5);
572 x_mul8_to(
unsigned int result,
unsigned int a,
unsigned int b,
573 unsigned int tmp1,
unsigned int tmp2) {
598 i_beq(tmp1, 0, mul8_not1);
599 i_add(result, result, a);
607 i_beq(tmp2, tmp1, mul8_end);
646 x_or_to(
unsigned int result,
unsigned int a,
unsigned int b) {
665 unsigned int tmp1,
unsigned int tmp2) {
688 i_beq(tmp2, 0, rshift_bit0);
691 i_add(result, result, tmp1);
696 i_beq(tmp1, 0, rshift_end);
706 unsigned int tmp1,
unsigned int tmp2) {
728 i_beq(tmp1, 0, rshift_8_5th_end);
731 i_beq(tmp1, tmp2, rshift_8_5th_masked_1);
734 i_beq(tmp1, tmp2, rshift_8_5th_masked_2);
736 i_addi(result, result, 0x3);
739 rshift_8_5th_masked_2:
740 i_addi(result, result, 0x2);
743 rshift_8_5th_masked_1:
744 i_addi(result, result, 0x1);
753 i_beq(tmp1, 0, rshift_8_6th_end);
756 i_beq(tmp1, tmp2, rshift_8_6th_masked_1);
759 i_beq(tmp1, tmp2, rshift_8_6th_masked_2);
761 i_addi(result, result, 0xC);
764 rshift_8_6th_masked_2:
765 i_addi(result, result, 0x8);
768 rshift_8_6th_masked_1:
769 i_addi(result, result, 0x4);
778 i_beq(tmp1, 0, rshift_8_7th_end);
781 i_beq(tmp1, tmp2, rshift_8_7th_masked_1);
784 i_beq(tmp1, tmp2, rshift_8_7th_masked_2);
786 i_addi(result, result, 0x30);
789 rshift_8_7th_masked_2:
790 i_addi(result, result, 0x20);
793 rshift_8_7th_masked_1:
794 i_addi(result, result, 0x10);
803 i_beq(tmp1, 0, rshift_8_8th_end);
806 i_beq(tmp1, tmp2, rshift_8_8th_masked_1);
809 i_beq(tmp1, tmp2, rshift_8_8th_masked_2);
812 i_add(result, result, tmp1);
815 rshift_8_8th_masked_2:
817 i_add(result, result, tmp1);
820 rshift_8_8th_masked_1:
822 i_add(result, result, tmp1);
831 unsigned int result_b,
unsigned int b,
832 unsigned int tmp1,
unsigned int tmp2,
unsigned int tmp3) {
833 assert(0 < result_a);
839 assert(0 < result_b);
864 i_beq(tmp1, 0, rshift_8_a_5th_end);
867 i_beq(tmp1, tmp2, rshift_8_a_5th_masked_1);
870 i_beq(tmp1, tmp2, rshift_8_a_5th_masked_2);
872 i_addi(result_a, result_a, 0x3);
875 rshift_8_a_5th_masked_2:
876 i_addi(result_a, result_a, 0x2);
879 rshift_8_a_5th_masked_1:
880 i_addi(result_a, result_a, 0x1);
887 i_beq(tmp1, 0, rshift_8_b_5th_end);
890 i_beq(tmp1, tmp2, rshift_8_b_5th_masked_1);
893 i_beq(tmp1, tmp2, rshift_8_b_5th_masked_2);
895 i_addi(result_b, result_b, 0x3);
898 rshift_8_b_5th_masked_2:
899 i_addi(result_b, result_b, 0x2);
902 rshift_8_b_5th_masked_1:
903 i_addi(result_b, result_b, 0x1);
912 i_beq(tmp1, 0, rshift_8_a_6th_end);
915 i_beq(tmp1, tmp2, rshift_8_a_6th_masked_1);
918 i_beq(tmp1, tmp2, rshift_8_a_6th_masked_2);
920 i_addi(result_a, result_a, 0xC);
923 rshift_8_a_6th_masked_2:
924 i_addi(result_a, result_a, 0x8);
927 rshift_8_a_6th_masked_1:
928 i_addi(result_a, result_a, 0x4);
935 i_beq(tmp1, 0, rshift_8_b_6th_end);
938 i_beq(tmp1, tmp2, rshift_8_b_6th_masked_1);
941 i_beq(tmp1, tmp2, rshift_8_b_6th_masked_2);
943 i_addi(result_b, result_b, 0xC);
946 rshift_8_b_6th_masked_2:
947 i_addi(result_b, result_b, 0x8);
950 rshift_8_b_6th_masked_1:
951 i_addi(result_b, result_b, 0x4);
960 i_beq(tmp1, 0, rshift_8_a_7th_end);
963 i_beq(tmp1, tmp2, rshift_8_a_7th_masked_1);
966 i_beq(tmp1, tmp2, rshift_8_a_7th_masked_2);
968 i_addi(result_a, result_a, 0x30);
971 rshift_8_a_7th_masked_2:
972 i_addi(result_a, result_a, 0x20);
975 rshift_8_a_7th_masked_1:
976 i_addi(result_a, result_a, 0x10);
983 i_beq(tmp1, 0, rshift_8_b_7th_end);
986 i_beq(tmp1, tmp2, rshift_8_b_7th_masked_1);
989 i_beq(tmp1, tmp2, rshift_8_b_7th_masked_2);
991 i_addi(result_b, result_b, 0x30);
994 rshift_8_b_7th_masked_2:
995 i_addi(result_b, result_b, 0x20);
998 rshift_8_b_7th_masked_1:
999 i_addi(result_b, result_b, 0x10);
1008 i_beq(tmp1, 0, rshift_8_a_8th_end);
1011 i_beq(tmp1, tmp2, rshift_8_a_8th_masked_1);
1014 i_beq(tmp1, tmp2, rshift_8_a_8th_masked_2);
1017 i_add(result_a, result_a, tmp1);
1020 rshift_8_a_8th_masked_2:
1022 i_add(result_a, result_a, tmp1);
1025 rshift_8_a_8th_masked_1:
1027 i_add(result_a, result_a, tmp1);
1034 i_beq(tmp1, 0, rshift_8_b_8th_end);
1037 i_beq(tmp1, tmp2, rshift_8_b_8th_masked_1);
1040 i_beq(tmp1, tmp2, rshift_8_b_8th_masked_2);
1043 i_add(result_b, result_b, tmp1);
1046 rshift_8_b_8th_masked_2:
1048 i_add(result_b, result_b, tmp1);
1051 rshift_8_b_8th_masked_1:
1053 i_add(result_b, result_b, tmp1);
1062 unsigned int tmp1,
unsigned int tmp2,
1063 unsigned int tmp3) {
1085 i_beq(tmp3, 0, rshift_8_signed_end);
1087 i_add(result, result, tmp1);
1088 rshift_8_signed_end:
1098 i_add(result, 0, 0);
1112 x_sqr(
unsigned int a,
unsigned int result2,
1113 unsigned int tmp1,
unsigned int tmp2,
unsigned int tmp3,
1114 unsigned int tmp4,
unsigned int tmp5) {
1118 assert(0 < result2);
1157 x_sqr8_to(result2, tmp2, tmp3, tmp4, tmp5);
1162 x_mul8_to(tmp1, tmp2, tmp3, tmp4, tmp5);
1172 x_add32(result2, a, tmp2, tmp1, tmp3, tmp4, tmp5);
1180 unsigned int tmp1,
unsigned int tmp2,
unsigned int tmp3) {
1208 i_beq(tmp1, 0, sqr8_not1);
1209 i_add(result, result, a);
1217 i_beq(tmp2, tmp1, sqr8_end);
1240 x_sub_to(
unsigned int result,
unsigned int a,
unsigned int b) {
1258 x_swap(
unsigned int a,
unsigned int b,
unsigned int tmp) {
void p_movi(unsigned int result, immed_t immed)
(MOV Immediate) R[result] <– immed
void x_mask0x8000(unsigned int a, unsigned int tmp)
R[a] <– R[a] & 0x8000 (== R[a] & 0b1000000000000000 == R[a] & 32768)
#define ASSERT_7_DIFFERENT(a, b, c, d, e, f, g)
Check if a, b, c, d, e, f and g are different.
#define x_branch(label)
Jump to label.
void x_neg(unsigned int a)
R[a] <– -R[a] (two's complement)
void x_not_to(unsigned int result, unsigned int a)
R[result] <– ~R[a].
void x_sqr(unsigned int a, unsigned int result2, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3, unsigned int tmp4, unsigned int tmp5)
R[result2]:R[a] <– R[a]*R[a].
void x_lshift(unsigned int a)
R[a] <– R[a] << 1 (== R[a]*2)
void x_sqr8_to(unsigned int result, unsigned int a, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[result] <– R[a] * R[a].
void x_mul8_to(unsigned int result, unsigned int a, unsigned int b, unsigned int tmp1, unsigned int tmp2)
R[result] <– R[a] * R[b].
void x_set0x8000(unsigned int a)
R[result] <– 0x8000 (== 0b1000000000000000 == 32768)
void x_inc32(unsigned int a2, unsigned int a1)
R[a2]:R[a1] <– R[a2]:R[a1] + 1.
void i_addi(unsigned int result, unsigned int a, immed_t immed6)
(ADD Immediate) R[result] <– R[a] + immed6
void x_not(unsigned int a)
R[a] <– ~R[a].
void x_mov(unsigned int result, unsigned int a)
R[result] <– R[a].
#define ASSERT_5_DIFFERENT(a, b, c, d, e)
Check if a, b, c, d and e are different.
#define i_beq(a, b, label)
(Branch if EQual) If R[a] == R[b] then jump to label.
void i_add(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] + R[b].
void x_mul_karatsuba(unsigned int a, unsigned int b, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3, unsigned int tmp4, unsigned int tmp5)
R[b]:R[a] <– R[a] * R[b] by Karatsuba algorithm: https://en.wikipedia.org/wiki/Karatsuba_algorithm.
word16_t registers[8]
Registers.
void x_rshift_8_to(unsigned int result, unsigned int a, unsigned int tmp1, unsigned int tmp2)
R[result] <– R[a] >> 8 (== R[a]/256)
void x_and_to(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] & R[b].
void x_add32(unsigned int a2, unsigned int a1, unsigned int b2, unsigned int b1, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[a2]:R[a1] <– R[a2]:R[a1] + R[b2]:R[b1].
const unsigned int nb_registers
Number of registers: 8 word16_t items.
void x_mul(unsigned int a, unsigned int b, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3, unsigned int tmp4, unsigned int tmp5)
R[b]:R[a] <– R[a] * R[b] by standard algorithm: https://en.wikipedia.org/wiki/Multiplication_algorit...
void x_addc(unsigned int a, unsigned int b, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[b]:R[a] <– R[a] + R[b].
void x_lshift32(unsigned int a2, unsigned int a1, unsigned int tmp)
R[a2]:R[a1] <– (R[a2]:R[a1]) << 1 (== (R[a2]:R[a1])*2)
void i_sw(unsigned int a, unsigned int result, immed_t immed6)
(Store Word) Memory[R[result] + immed6] <– R[a]
void x_rshift_8_duo_to(unsigned int result_a, unsigned int a, unsigned int result_b, unsigned int b, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[resulta] <– R[a] >> 8 (== R[a]/256) R[resultb] <– R[b] >> 8.
void x_sub_to(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] - R[b].
#define ASSERT_4_DIFFERENT(a, b, c, d)
Check if a, b, c and d are different.
void x_swap(unsigned int a, unsigned int b, unsigned int tmp)
R[a], R[b] <– R[b], R[a].
void x_lshift32_8(unsigned int a2, unsigned int a1, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[a2]:R[a1] <– (R[a2]:R[a1]) << 8 (== (R[a2]:R[a1])*256)
void x_lshift_8(unsigned int a)
R[a] <– R[a] << 8 (== R[a]*256)
void x_rshift_to(unsigned int result, unsigned int a, unsigned int tmp1, unsigned int tmp2)
R[result] <– R[a] >> 1 (== R[a]/2)
void x_set0(unsigned int result)
R[a] <– 0.
void x_lshift_to(unsigned int result, unsigned int a)
R[result] <– R[a] << 1 (== R[a]*2)
void x_is_lower_to(unsigned int result, unsigned int a, unsigned int b, unsigned int tmp)
R[result] <– (positive value) if a < b, 0 else.
void x_sub_from(unsigned int a, unsigned int b)
R[a] <– -R[a] + R[b].
void x_lshift_8_to(unsigned int result, unsigned int a)
R[result] <– R[a] << 8 (== R[a]*256)
void x_or_to(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] | R[b].
Extended instructions set: some extra operations x_* implemented with RiSC16.
void i_nand(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] NAND R[b] (== ~(a & b))
void x_mask0x8000_to(unsigned int result, unsigned int a)
R[result] <– R[a] & 0x8000 (== R[a] & 0b1000000000000000 == R[a] & 32768)
void x_rshift_8_signed_to(unsigned int result, unsigned int a, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[result] <– R[a] >> 8 with extension of the sign.
void i_lw(unsigned int result, unsigned int a, immed_t immed6)
(Load Word) R[result] <– Memory[R[a] + immed6]
void i_lui(unsigned int result, immed_t immed10)
(Load Upper Immediate) R[result] <– immed10 << 6
#define ASSERT_3_DIFFERENT(a, b, c)
Check if a, b and c are different.