Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
26f6ddc
Add Compiler-RT for 128bit integer support
jkthorne Oct 11, 2019
15b0804
Add specs for Compiler-RT
jkthorne Oct 11, 2019
3d21d8e
skip 32bits flag to compiler-rt specs
jkthorne Oct 11, 2019
c7abe38
Use record over struct; put info structs into same file;
jkthorne Oct 11, 2019
f86dd9c
change flags in specs; require info file
jkthorne Oct 11, 2019
b783fc3
revert struct to record
jkthorne Oct 11, 2019
380fc90
used overflows in compiler-rt functions
jkthorne Oct 11, 2019
ca2592e
fix 32bit tests
jkthorne Oct 11, 2019
bd6a9d9
use extern for strructs
jkthorne Oct 11, 2019
1663b66
use // in udivmodti
jkthorne Oct 11, 2019
106f403
reorder the rt require functions
jkthorne Oct 11, 2019
a8ed506
update to use c structs
jkthorne Oct 12, 2019
5887248
Merge branch 'master' into i128_compiler_rt
jkthorne Oct 12, 2019
0f30e9e
cleanup unused fun
jkthorne Oct 12, 2019
6c7828d
disable tests the require i128 parsing
jkthorne Oct 12, 2019
9fdad45
re-enabled __mulodi4 specs
jkthorne Oct 12, 2019
3ee5faf
revert format fix
jkthorne Oct 12, 2019
dcd39ea
Merge branch 'master' into i128_compiler_rt
jkthorne Oct 16, 2019
6543eb3
add __umodti3 to compiler-rt
jkthorne Oct 16, 2019
6aef69a
add udivti3 fun to compiler-rt
jkthorne Oct 16, 2019
38acdb6
fix formatting
jkthorne Oct 17, 2019
899b303
break up tests files
jkthorne Oct 17, 2019
72c7c9b
break up test files for ci
jkthorne Oct 17, 2019
d780875
update rtinfo to use #all methos
jkthorne Oct 17, 2019
534ca68
Merge branch 'master' into i128_compiler_rt
jkthorne Oct 17, 2019
21d7a7e
update test_darwin to 11.1
jkthorne Oct 17, 2019
ed5841d
update xcode in circleci to 11.1.0
jkthorne Oct 18, 2019
3e993f6
Apply suggestions from code review
jkthorne Oct 18, 2019
88b7d88
Apply suggestions from code review
jkthorne Oct 18, 2019
f603253
update udivmodti4
jkthorne Oct 18, 2019
83b58f4
revert xcode to 9.0
jkthorne Oct 18, 2019
22226a2
Merge branch 'master' into i128_compiler_rt
jkthorne Oct 19, 2019
8c5cf0f
remove puts statement
jkthorne Oct 19, 2019
c2ead94
use bits32 flag for compiler-rt files
jkthorne Oct 19, 2019
e351c94
first pass update on specs
jkthorne Oct 19, 2019
3e89f07
first pass at test isolation
jkthorne Oct 19, 2019
c05dd49
first pass at test isolation
jkthorne Oct 19, 2019
e8b38d5
fix merge conflict
jkthorne Oct 19, 2019
318c2cb
update udivmodti4 with tailing and leading zeros
jkthorne Oct 23, 2019
66aa14b
comment out tests that cannot be run yet
jkthorne Oct 23, 2019
d78fa01
Merge branch 'master' into i128_compiler_rt
jkthorne Oct 23, 2019
7b79a76
add comments to add tests for Int128 once support is added
jkthorne Oct 23, 2019
1950827
add mulddi3
jkthorne Oct 23, 2019
745d17b
fix positive integers for __multi3
jkthorne Oct 25, 2019
3db6b74
move initializers around
jkthorne Oct 25, 2019
a585a05
update int struct
jkthorne Oct 25, 2019
53ac00b
update muloti4
jkthorne Oct 25, 2019
adf6941
update multi3 style
jkthorne Oct 25, 2019
42a34b5
enable umodti3 specs
jkthorne Oct 25, 2019
e6eb8b2
update int 128 info layout
jkthorne Oct 25, 2019
4989978
add macros for i128 info structs
jkthorne Oct 25, 2019
46c55d1
use macros for muloti3 specs
jkthorne Oct 25, 2019
a6c3fb0
update the constructors in int info
jkthorne Oct 25, 2019
7a08b32
update divti3 and specs
jkthorne Oct 29, 2019
337b362
update __modti3 and specs
jkthorne Oct 29, 2019
fa55680
update muloti4 and specs
jkthorne Oct 29, 2019
fe5a9e4
complete multi3 specs
jkthorne Oct 29, 2019
b6b8220
update umodti3 with new patterns
jkthorne Oct 29, 2019
e884358
add flag for compile RT specs
jkthorne Oct 29, 2019
708bbb6
setup udivmodti4 for specs
jkthorne Oct 29, 2019
61affcf
formatting change and cleanup udivmodti4 specs
jkthorne Oct 29, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion spec/std/callstack_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ require "./spec_helper"

private def compile_and_run_file(source_file)
with_tempfile("executable_file") do |executable_file|
puts executable_file
Process.run("bin/crystal", ["build", "--debug", "-o", executable_file, source_file])
File.exists?(executable_file).should be_true

Expand Down
26 changes: 26 additions & 0 deletions spec/std/crystal/compiler_rt/divti3_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{% skip_file unless flag?(:compile_rt) %}

require "spec"
require "../../../../src/crystal/compiler_rt/divti3"
require "../../../../src/crystal/compiler_rt/i128_info"

# Ported from compiler-rt:test/builtins/Unit/divti3_test.c

private def test__divti3(a : (Int128 | Int128RT), b : (Int128 | Int128RT), expected : (Int128 | Int128RT), file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
__divti3(a.to_i128, b.to_i128).should eq(expected.to_i128), file, line
end
end

describe "__divti3" do
test__divti3(0_i128, 1_i128, 0_i128)
test__divti3(0_i128, Int128RT[1_i128].negate!, 0_i128)
test__divti3(2_i128, 1_i128, 2_i128)
test__divti3(2_i128, Int128RT[1_i128].negate!, Int128RT[2_i128].negate!)
test__divti3(Int128RT[2_i128].negate!, 1_i128, Int128RT[2_i128].negate!)
test__divti3(Int128RT[2_i128].negate!, Int128RT[1_i128].negate!, 2_i128)
test__divti3(Int128RT[-9223372036854775808_i64, 0_u64], 1_i128, Int128RT[-9223372036854775808_i64, 0_u64])
test__divti3(Int128RT[-9223372036854775808_i64, 0_u64], Int128RT[1_i128].negate!, Int128RT[-9223372036854775808_i64, 0_u64])
test__divti3(Int128RT[-9223372036854775808_i64, 0_u64], Int128RT[2_i128].negate!, Int128RT[4611686018427387904_i64, 0_u64])
test__divti3(Int128RT[-9223372036854775808_i64, 0_u64], 2_i128, Int128RT[-4611686018427387904_i64, 0_u64])
end
28 changes: 28 additions & 0 deletions spec/std/crystal/compiler_rt/modti3_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{% skip_file unless flag?(:compile_rt) %}

require "spec"
require "../../../../src/crystal/compiler_rt/modti3"
require "../../../../src/crystal/compiler_rt/i128_info"

# Ported from compiler-rt:test/builtins/Unit/modti3_test.c

private def test__modti3(a : (Int128 | Int128RT), b : (Int128 | Int128RT), expected : (Int128 | Int128RT), file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
__modti3(a.to_i128, b.to_i128).should eq(expected.to_i128), file, line
end
end

describe "__modti3" do
test__modti3(0_i128, 1_i128, 0_i128)
test__modti3(0_i128, Int128RT[1_i128].negate!, 0_i128)
test__modti3(5_i128, 3_i128, 2_i128)
test__modti3(5_i128, Int128RT[3_i128].negate!, 2_i128)
test__modti3(Int128RT[5_i128].negate!, 3_i128, Int128RT[2_i128].negate!)
test__modti3(Int128RT[5_i128].negate!, Int128RT[3_i128].negate!, Int128RT[2_i128].negate!)
test__modti3(Int128RT[-9223372036854775808_i64, 0_u64], 1_i128, 0_i128)
test__modti3(Int128RT[-9223372036854775808_i64, 0_u64], Int128RT[1_i128].negate!, 0_i128)
test__modti3(Int128RT[-9223372036854775808_i64, 0_u64], 2_i128, 0_i128)
test__modti3(Int128RT[-9223372036854775808_i64, 0_u64], Int128RT[2_i128].negate!, 0_i128)
# test__modti3(Int128RT[-9223372036854775808_i64, 0_u64], 3_i128, Int128RT[2_i128].negate!)
# test__modti3(Int128RT[-9223372036854775808_i64, 0_u64], Int128RT[3_i128].negate!, Int128RT[2_i128].negate!)
end
3 changes: 3 additions & 0 deletions spec/std/crystal/compiler_rt/mulodi4_spec.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{% skip_file unless flag?(:compile_rt) %}

require "spec"
require "../../../../src/crystal/compiler_rt/mulodi4.cr"

# Ported from compiler-rt:test/builtins/Unit/mulodi4_test.c

Expand Down
95 changes: 95 additions & 0 deletions spec/std/crystal/compiler_rt/muloti4_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
{% skip_file unless flag?(:compile_rt) %}

require "spec"
require "../../../../src/crystal/compiler_rt/muloti4"
require "../../../../src/crystal/compiler_rt/i128_info"

# Ported from compiler-rt:test/builtins/Unit/muloti4_test.c

private def test__muloti4(a : (Int128 | Int128RT), b : (Int128 | Int128RT), expected : (Int128 | Int128RT), expected_overflow : Int32, file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
actual_overflow : Int32 = 0
actual = __muloti4(a.to_i128, b.to_i128, pointerof(actual_overflow))
actual_overflow.should eq(expected_overflow), file, line
if !expected_overflow
actual.should eq(expected.to_i128), file, line
end
end
end

describe "__muloti4" do
test__muloti4(0_i128, 0_i128, 0_i128, 0)
test__muloti4(0_i128, 1_i128, 0_i128, 0)
test__muloti4(1_i128, 0_i128, 0_i128, 0)
test__muloti4(0_i128, 10_i128, 0_i128, 0)
test__muloti4(10_i128, 0_i128, 0_i128, 0)
test__muloti4(0_i128, 81985529216486895_i128, 0_i128, 0)
test__muloti4(81985529216486895_i128, 0, 0, 0)

test__muloti4(0_i128, Int128RT[1_i128].negate!, 0_i128, 0)
test__muloti4(Int128RT[1_i128].negate!, 0_i128, 0_i128, 0)
test__muloti4(0_i128, Int128RT[10_i128].negate!, 0_i128, 0)
test__muloti4(Int128RT[10_i128].negate!, 0_i128, 0_i128, 0)
test__muloti4(0_i128, Int128RT[81985529216486895_i128].negate!, 0_i128, 0)
test__muloti4(Int128RT[81985529216486895_i128].negate!, 0_i128, 0_i128, 0)

test__muloti4(1_i128, 1_i128, 1_i128, 0)
test__muloti4(1_i128, 10_i128, 10_i128, 0)
test__muloti4(10_i128, 1_i128, 10_i128, 0)
test__muloti4(1_i128, 81985529216486895_i128, 81985529216486895_i128, 0)
test__muloti4(81985529216486895_i128, 1_i128, 81985529216486895_i128, 0)

test__muloti4(1_i128, Int128RT[1_i128].negate!, Int128RT[1_i128].negate!, 0)
test__muloti4(1_i128, Int128RT[10_i128].negate!, Int128RT[10_i128].negate!, 0)
test__muloti4(Int128RT[10_i128].negate!, 1_i128, Int128RT[10_i128].negate!, 0)
test__muloti4(1_i128, Int128RT[81985529216486895_i128].negate!, Int128RT[81985529216486895_i128].negate!, 0)
test__muloti4(Int128RT[81985529216486895_i128].negate!, 1_i128, Int128RT[81985529216486895_i128].negate!, 0)

test__muloti4(3037000499_i128, 3037000499_i128, 9223372030926249001_i128, 0)
test__muloti4(Int128RT[3037000499_i128].negate!, 3037000499_i128, Int128RT[9223372030926249001_i128].negate!, 0)
test__muloti4(3037000499_i128, Int128RT[3037000499_i128].negate!, Int128RT[9223372030926249001_i128].negate!, 0)
test__muloti4(Int128RT[3037000499_i128].negate!, Int128RT[3037000499_i128].negate!, 9223372030926249001_i128, 0)

test__muloti4(4398046511103_i128, 2097152_i128, 9223372036852678656_i128, 0)
test__muloti4(Int128RT[4398046511103_i128].negate!, 2097152_i128, Int128RT[9223372036852678656_i128].negate!, 0)
test__muloti4(4398046511103_i128, Int128RT[2097152_i128].negate!, Int128RT[9223372036852678656_i128].negate!, 0)
test__muloti4(Int128RT[4398046511103_i128].negate!, Int128RT[2097152_i128].negate!, 9223372036852678656_i128, 0)

test__muloti4(2097152_i128, 4398046511103_i128, 9223372036852678656_i128, 0)
test__muloti4(Int128RT[2097152_i128].negate!, 4398046511103_i128, Int128RT[9223372036852678656_i128].negate!, 0)
test__muloti4(2097152_i128, Int128RT[4398046511103_i128].negate!, Int128RT[9223372036852678656_i128].negate!, 0)
test__muloti4(Int128RT[2097152_i128].negate!, Int128RT[4398046511103_i128].negate!, 9223372036852678656_i128, 0)

# test__muloti4(Int128RT[0x00000000000000B5_i64, 0x04F333F9DE5BE000_u64], Int128RT[0x0000000000000000_i64, 0x00B504F333F9DE5B_u64], Int128RT[0x7FFFFFFFFFFFF328_i64, 0xDF915DA296E8A000_u64], 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are there so many commented out tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are broken. The main problem is __udivmodti4 but it is hard to debug and I work on one failure at a time. I have gotten enough help from these PRs that I can close them and reopen them when I am closer if that helps.

Copy link
Member

@RX14 RX14 Nov 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is WIP, then could you please indicate that in the title?

test__muloti4(Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], Int128RT[2_i128].negate!, Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 1)
test__muloti4(Int128RT[2_i128].negate!, Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 1)
test__muloti4(Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], Int128RT[1_i128].negate!, Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 0)
test__muloti4(Int128RT[1_i128].negate!, Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 0)
test__muloti4(Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], 0_i128, 0_i128, 0)
test__muloti4(0_i128, Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], 0_i128, 0)
test__muloti4(Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], 1_i128, Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], 0)
test__muloti4(1_i128, Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], 0)
test__muloti4(Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], 2_i128, Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 1)
test__muloti4(2_i128, Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 1)
# test__muloti4(Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], Int128RT[2_i128].negate!, Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 1)
# test__muloti4(Int128RT[2_i128].negate!, Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 1)
# test__muloti4(Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], Int128RT[1_i128].negate!, Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 1)
# test__muloti4(Int128RT[1_i128].negate!, Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 1)
test__muloti4(Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 0_i128, 0_i128, 0)
test__muloti4(0_i128, Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 0_i128, 0)
test__muloti4(Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 1_i128, Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 0)
test__muloti4(1_i128, Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 0)
# test__muloti4(Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 2_i128, Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 1)
# test__muloti4(2_i128, Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 1)

# test__muloti4(Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], Int128RT[2_i128].negate!, Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 1)
# test__muloti4(Int128RT[2_i128].negate!, Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 1)
test__muloti4(Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], Int128RT[1_i128].negate!, Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], 0)
test__muloti4(Int128RT[1_i128].negate!, Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], Int128RT[0x7FFFFFFFFFFFFFFF_i64, 0xFFFFFFFFFFFFFFFF_u64], 0)
test__muloti4(Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 0_i128, 0_i128, 0)
test__muloti4(0_i128, Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 0_i128, 0)
test__muloti4(Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 1_i128, Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 0)
test__muloti4(1_i128, Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 0)
# test__muloti4(Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], 2_i128, Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 1)
# test__muloti4(2_i128, Int128RT[-9223372036854775808_i64, 0x0000000000000001_u64], Int128RT[-9223372036854775808_i64, 0x0000000000000000_u64], 1)
end
51 changes: 51 additions & 0 deletions spec/std/crystal/compiler_rt/multi3_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{% skip_file unless flag?(:compile_rt) %}

require "spec"
require "../../../../src/crystal/compiler_rt/multi3.cr"

# Ported from compiler-rt:test/builtins/Unit/multi3_test.c

private def test__multi3(a : (Int128 | Int128RT), b : (Int128 | Int128RT), expected : (Int128 | Int128RT), file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
__multi3(a.to_i128, b.to_i128).should eq(expected.to_i128), file, line
end
end

describe "__multi3" do
test__multi3(0_i128, 0_i128, 0_i128)
test__multi3(0_i128, 1_i128, 0_i128)
test__multi3(1_i128, 0_i128, 0_i128)
test__multi3(0_i128, 10_i128, 0_i128)
test__multi3(10_i128, 0_i128, 0_i128)
test__multi3(0_i128, 81985529216486895_i128, 0_i128)
test__multi3(81985529216486895_i128, 0_i128, 0_i128)
test__multi3(0_i128, Int128RT[1_i128].negate!, 0_i128)
test__multi3(Int128RT[1_i128].negate!, 0_i128, 0_i128)
test__multi3(0_i128, Int128RT[10_i128].negate!, 0_i128)
test__multi3(Int128RT[10_i128].negate!, 0_i128, 0_i128)
test__multi3(0_i128, Int128RT[81985529216486895_i128].negate!, 0_i128)
test__multi3(Int128RT[81985529216486895_i128].negate!, 0_i128, 0_i128)
test__multi3(1_i128, 1_i128, 1_i128)
test__multi3(1_i128, 10_i128, 10_i128)
test__multi3(10_i128, 1_i128, 10_i128)
test__multi3(1_i128, 81985529216486895_i128, 81985529216486895_i128)
test__multi3(81985529216486895_i128, 1_i128, 81985529216486895_i128)
test__multi3(1_i128, Int128RT[1_i128].negate!, Int128RT[1_i128].negate!)
test__multi3(1_i128, Int128RT[10_i128].negate!, Int128RT[10_i128].negate!)
test__multi3(Int128RT[10_i128].negate!, 1_i128, Int128RT[10_i128].negate!)
test__multi3(1_i128, Int128RT[81985529216486895_i128].negate!, Int128RT[81985529216486895_i128].negate!)
test__multi3(Int128RT[81985529216486895_i128].negate!, 1_i128, Int128RT[81985529216486895_i128].negate!)
test__multi3(3037000499_i128, 3037000499_i128, 9223372030926249001_i128)
test__multi3(Int128RT[3037000499_i128].negate!, 3037000499_i128, Int128RT[9223372030926249001_i128].negate!)
test__multi3(3037000499_i128, Int128RT[3037000499_i128].negate!, Int128RT[9223372030926249001_i128].negate!)
test__multi3(Int128RT[3037000499_i128].negate!, Int128RT[3037000499_i128].negate!, 9223372030926249001_i128)
test__multi3(4398046511103_i128, 2097152_i128, 9223372036852678656_i128)
test__multi3(Int128RT[4398046511103_i128].negate!, 2097152_i128, Int128RT[9223372036852678656_i128].negate!)
test__multi3(4398046511103_i128, Int128RT[2097152_i128].negate!, Int128RT[9223372036852678656_i128].negate!)
test__multi3(Int128RT[4398046511103_i128].negate!, Int128RT[2097152_i128].negate!, 9223372036852678656_i128)
test__multi3(2097152_i128, 4398046511103_i128, 9223372036852678656_i128)
test__multi3(Int128RT[2097152_i128].negate!, 4398046511103_i128, Int128RT[9223372036852678656_i128].negate!)
test__multi3(2097152_i128, Int128RT[4398046511103_i128].negate!, Int128RT[9223372036852678656_i128].negate!)
test__multi3(Int128RT[2097152_i128].negate!, Int128RT[4398046511103_i128].negate!, 9223372036852678656_i128)
test__multi3(Int128RT[0x00000000000000B5_i64, 0x04F333F9DE5BE000_u64].all, Int128RT[0x0000000000000000_i64, 0x00B504F333F9DE5B_u64].all, Int128RT[0x7FFFFFFFFFFFF328_i64, 0xDF915DA296E8A000_u64].all)
end
28 changes: 28 additions & 0 deletions spec/std/crystal/compiler_rt/udivmodti4_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{% skip_file unless flag?(:compile_rt) %}

require "spec"
require "../../../../src/crystal/compiler_rt/udivmodti4.cr"

# Ported from compiler-rt:test/builtins/Unit/udivmodti4_test.c

private def test__udivmodti4(a : (UInt128 | UInt128RT), b : (UInt128 | UInt128RT), expected : (UInt128 | UInt128RT), expected_overflow : (UInt128 | UInt128RT), file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
actual_overflow = 0_u128
actual = __udivmodti4(a.to_u128, b.to_u128, pointerof(actual_overflow))
actual_overflow.should eq(expected_overflow.to_u128), file, line
if !expected_overflow.to_u128
actual.should eq(expected.to_u128), file, line
end
end
end

private UDIVMODTI4_TESTS = StaticArray[
StaticArray[UInt128RT[1_i128], UInt128RT[1_i128], UInt128RT[1_i128], UInt128RT[0_i128]],
# # TODO: this is a placeholder, remove when ready
]

describe "__udivmodti4" do
UDIVMODTI4_TESTS.each do |tests|
test__udivmodti4(tests[0], tests[1], tests[2], tests[3])
end
end
20 changes: 20 additions & 0 deletions spec/std/crystal/compiler_rt/umodti3_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% skip_file unless flag?(:compile_rt) %}

require "spec"
require "../../../../src/crystal/compiler_rt/umodti3"

# Ported from compiler-rt:test/builtins/Unit/umodti3_test.c

private def test__umodti3(a : (UInt128 | UInt128RT), b : (UInt128 | UInt128RT), expected : (UInt128 | UInt128RT), file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
__umodti3(a.to_u128, b.to_u128).should eq(expected.to_u128), file, line
end
end

describe "__umodti3" do
test__umodti3(0_u128, 1_u128, 0_u128)
test__umodti3(2_u128, 1_u128, 0_u128)
test__umodti3(UInt128RT[0x0000000000000000_u64, 0x8000000000000000_u64], 1_u128, 0_u128)
test__umodti3(UInt128RT[0x0000000000000000_u64, 0x8000000000000000_u64], 2_u128, 0_u128)
test__umodti3(UInt128RT[0xFFFFFFFFFFFFFFFF_u64, 0xFFFFFFFFFFFFFFFF_u64], 2_u128, 1_u128)
end
2 changes: 2 additions & 0 deletions spec/std/int_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ describe "Int" do
(-13 % -4).should eq(-1)
end

# TODO: add Int128 once implemented
it "returns 0 when doing IntN::MIN % -1 (#8306)" do
{% for n in [8, 16, 32, 64] %}
(Int{{n}}::MIN % -1_i{{n}}).should eq(0)
Expand All @@ -523,6 +524,7 @@ describe "Int" do
-13.remainder(-4).should eq(-1)
end

# TODO: add Int128 once implemented
it "returns 0 when doing IntN::MIN.remainder(-1) (#8306)" do
{% for n in [8, 16, 32, 64] %}
(Int{{n}}::MIN.remainder(-1_i{{n}})).should eq(0)
Expand Down
4 changes: 4 additions & 0 deletions src/crystal/compiler_rt.cr
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Low Level Runtime Functions for LLVM.
# The function definitions and explinations can be found here.
# https://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc

{% skip_file if flag?(:skip_crystal_compiler_rt) %}

require "./compiler_rt/mulodi4.cr"
14 changes: 14 additions & 0 deletions src/crystal/compiler_rt/divti3.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require "./udivmodti4"

# Function returning quotient for signed division eg `a / b`

fun __divti3(a : Int128, b : Int128) : Int128
bits_in_tword_m1 = (sizeof(Int128) &* sizeof(Char)) &- 1
s_a = a >> bits_in_tword_m1
s_b = b >> bits_in_tword_m1
a = (a ^ s_a) &- s_a
b = (b ^ s_b) &- s_b
s_a ^= s_b
r = 0_u128
((__udivmodti4(a.unsafe_as(UInt128), b.unsafe_as(UInt128), pointerof(r)) ^ s_a) &- s_a).unsafe_as(Int128)
end
37 changes: 37 additions & 0 deletions src/crystal/compiler_rt/i128_info.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@[Extern]
struct Int128Info
property low : UInt64 = 0_u64
property high : Int64 = 0_i64
end

@[Extern(union: true)]
struct Int128RT
property all : Int128 = 0_i128
property info : Int128Info = Int128Info.new

macro [](high, low)
%i_info = uninitialized Int128RT
%i_info.info.high = {{high}}.unsafe_as(Int64)
%i_info.info.low = {{low}}.unsafe_as(UInt64)
%i_info
end

macro [](high)
%i_info = uninitialized Int128RT
%i_info.all = {{high}}.unsafe_as(Int128)
%i_info
end

def negate!
self.all = self.all * -1
self
end

def to_i128
all
end

def debug
printf("%x:%x\n", info.high, info.low)
end
end
14 changes: 14 additions & 0 deletions src/crystal/compiler_rt/modti3.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require "./udivmodti4"

# Function return the remainder of the signed division eg. `a % b`

fun __modti3(a : Int128, b : Int128) : Int128
bits_in_tword_m1 = sizeof(Int128) &* sizeof(Char) &- 1
s = b >> bits_in_tword_m1
b = (b ^ s) &- s
s = a >> bits_in_tword_m1
a = (a ^ s) &- s
r = 0_u128
__udivmodti4(a.unsafe_as(UInt128), b.unsafe_as(UInt128), pointerof(r))
(r ^ s).unsafe_as(Int128) &- s # negate if s == -1
end
24 changes: 24 additions & 0 deletions src/crystal/compiler_rt/mulddi3.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require "./i128_info"

# Functions for returning the product of signed integer multiplication eg. `a * b`

fun __mulddi3(a : UInt64, b : UInt64) : Int128
r = Int128RT.new
bits_in_dword_2 = sizeof(UInt128) * sizeof(Char) // 2
lower_mask = ~0_u64 >> bits_in_dword_2

r.info.low = (a & lower_mask) &* (b & lower_mask)
t = r.info.low >> bits_in_dword_2
r.info.low = r.info.low & lower_mask
t += (a >> bits_in_dword_2) &* (b & lower_mask)
r.info.low = (r.info.low &+ ((t & lower_mask) << bits_in_dword_2))
r.info.high = (t >> bits_in_dword_2).unsafe_as(Int64)
t = r.info.low >> bits_in_dword_2
r.info.low = r.info.low & lower_mask
t += (b >> bits_in_dword_2) &* (a & lower_mask)
r.info.low = (r.info.low &+ ((t & lower_mask) << bits_in_dword_2))
r.info.high = r.info.high &+ (t >> bits_in_dword_2)
r.info.high = r.info.high &+ ((a >> bits_in_dword_2) &* (b >> bits_in_dword_2))

r.all
end
2 changes: 2 additions & 0 deletions src/crystal/compiler_rt/mulodi4.cr
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Functions for returning the product of signed multiplication with overflow eg. `a * b`

fun __mulodi4(a : Int64, b : Int64, overflow : Int32*) : Int64
n = 64
min = Int64::MIN
Expand Down
Loading