Skip to content
This repository was archived by the owner on Sep 2, 2018. It is now read-only.

Commit e2a9559

Browse files
committed
Merge pull request #147 from avr-llvm/feature/on_target_execution_tests
[AVR] Add on-target execution tests
2 parents c5bf92f + 8464221 commit e2a9559

18 files changed

+1112
-2
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ tools/llgo
5656
tools/polly
5757
# Sphinx build tree, if building in-source dir.
5858
docs/_build
59+
# AVR on-target test suite library
60+
utils/AVR/avrlit/libavrlit/lufa
61+
utils/AVR/avrlit/libavrlit/*/_build
5962

6063
#==============================================================================#
6164
# Files created in tree by the Go bindings.

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ if( LLVM_INCLUDE_UTILS )
586586
add_subdirectory(utils/not)
587587
add_subdirectory(utils/llvm-lit)
588588
add_subdirectory(utils/yaml-bench)
589+
add_subdirectory(utils/AVR/avrlit)
589590
else()
590591
if ( LLVM_INCLUDE_TESTS )
591592
message(FATAL_ERROR "Including tests when not building utils will not work.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// RUN: llvm-avrlit %s %p/add.ll %p/and.ll %p/xor.ll
2+
3+
#include <avrlit.h>
4+
5+
using namespace avrlit;
6+
7+
//=== add.ll ==================================================================
8+
extern "C" {
9+
i8 add8_reg_reg(i8, i8);
10+
i8 add8_reg_imm(i8);
11+
i8 add8_reg_increment(i8);
12+
i16 add16_reg_reg(i16, i16);
13+
i16 add16_reg_imm(i16);
14+
i16 add16_reg_imm_subi(i16);
15+
i32 add32_reg_reg(i32, i32);
16+
i32 add32_reg_imm(i32);
17+
i64 add64_reg_reg(i64, i64);
18+
i64 add64_reg_imm(i64);
19+
}
20+
21+
void test_add(test & t) {
22+
t.plan(20, PSTR("ADD"));
23+
24+
t.ok(_(add8_reg_reg( 23, 42) == 23 + 42));
25+
t.ok(_(add8_reg_reg(-23, 42) == -23 + 42));
26+
27+
t.ok(_(add8_reg_imm(42) == 42 + 5));
28+
t.ok(_(add8_reg_imm(23) == 23 + 5));
29+
30+
t.ok(_(add8_reg_increment(42) == 42 + 1));
31+
t.ok(_(add8_reg_increment(23) == 23 + 1));
32+
33+
t.ok(_(add16_reg_reg(1234, 4321) == 1234 + 4321));
34+
t.ok(_(add16_reg_reg(5678, 8765) == 5678 + 8765));
35+
36+
t.ok(_(add16_reg_imm(1234) == 1234 + 63));
37+
t.ok(_(add16_reg_imm(8765) == 8765 + 63));
38+
39+
t.ok(_(add16_reg_imm_subi(1234) == 1234 + 123));
40+
t.ok(_(add16_reg_imm_subi(8765) == 8765 + 123));
41+
42+
t.ok(_(add32_reg_reg(123456, 987654) == 123456 + 987654));
43+
t.ok(_(add32_reg_reg(3, 5) == 3 + 5));
44+
45+
t.ok(_(add32_reg_imm(987654) == 987654 + 5));
46+
t.ok(_(add32_reg_imm(5) == 5 + 5));
47+
48+
t.ok(_(add64_reg_reg(9876543210, 9988776655) ==
49+
9876543210 + 9988776655));
50+
t.ok(_(add64_reg_reg(198, 126) == 198 +126));
51+
52+
t.ok(_(add64_reg_imm(9876543210) == 9876543210 + 5));
53+
t.ok(_(add64_reg_imm(198) == 198 + 5));
54+
55+
}
56+
57+
//=== and.ll ==================================================================
58+
extern "C" {
59+
i8 and8_reg_reg(i8, i8);
60+
i8 and8_reg_imm(i8);
61+
i16 and16_reg_reg(i16, i16);
62+
i16 and16_reg_imm(i16);
63+
}
64+
65+
void test_and(test & t) {
66+
t.plan(8, PSTR("AND"));
67+
68+
t.ok(_(and8_reg_reg(23, 42) == (23 & 42)));
69+
t.ok(_(and8_reg_reg(0xef, 0x2a) == (0xef & 0x2a)));
70+
71+
t.ok(_(and8_reg_imm(23) == (23 & 5)));
72+
t.ok(_(and8_reg_imm(0xef) == (0xef & 5)));
73+
74+
t.ok(_(and16_reg_reg(2323, 4242) == (2323 & 4242)));
75+
t.ok(_(and16_reg_reg(0xefff, 0x2aaa) == (0xefff & 0x2aaa)));
76+
77+
t.ok(_(and16_reg_imm(2342) == (2342 & 1234)));
78+
t.ok(_(and16_reg_imm(0xefff) == (0xefff & 1234)));
79+
}
80+
81+
//=== xor.ll ==================================================================
82+
extern "C" {
83+
i8 xor8_reg_reg(i8, i8);
84+
i16 xor16_reg_reg(i16, i16);
85+
i32 xor32_reg_reg(i32, i32);
86+
i64 xor64_reg_reg(i64, i64);
87+
}
88+
89+
void test_xor(test & t) {
90+
t.plan(8, PSTR("XOR"));
91+
92+
t.ok(_(xor8_reg_reg(23, 42) == 23 ^ 42));
93+
t.ok(_(xor8_reg_reg(0xff, 0xaa) == 0xff ^ 0xaa));
94+
95+
t.ok(_(xor16_reg_reg(0xffff, 0xaaaa) == 0xffff ^ 0xaaaa));
96+
t.ok(_(xor16_reg_reg(0x5555, 0xaaaa) == 0x5555 ^ 0xaaaa));
97+
98+
t.ok(_(xor32_reg_reg(0xffffffff, 0xaaaaaaaa) ==
99+
0xffffffff ^ 0xaaaaaaaa));
100+
t.ok(_(xor32_reg_reg(0x55555555, 0xaaaaaaaa) ==
101+
0x55555555 ^ 0xaaaaaaaa));
102+
103+
t.ok(_(xor64_reg_reg(0xffffffffffffffff, 0xaaaaaaaaaaaaaaaa) ==
104+
0xffffffffffffffff ^ 0xaaaaaaaaaaaaaaaa));
105+
t.ok(_(xor64_reg_reg(0x5555555555555555, 0xaaaaaaaaaaaaaaaa) ==
106+
0x5555555555555555 ^ 0xaaaaaaaaaaaaaaaa));
107+
}
108+
109+
//=== Test Suite ==============================================================
110+
111+
AVRLIT_TEST_SUITE() {
112+
run(test_add, test_and, test_xor);
113+
}
114+

test/CodeGen/AVR/lit.local.cfg

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
1-
config.suffixes = ['.ll']
1+
config.suffixes = ['.ll', '.cpp']
2+
3+
import os, lit.TestRunner
4+
from lit.formats import ShTest
25

36
targets = set(config.root.targets_to_build.split())
47
if not 'AVR' in targets:
5-
config.unsupported = True
8+
config.unsupported = True
9+
10+
if 'AVRLIT_PORT' in os.environ:
11+
config.environment['AVRLIT_PORT'] = os.environ['AVRLIT_PORT']
12+
13+
class AVRCodeGenTest(ShTest):
14+
def __init__(self):
15+
ShTest.__init__(self)
16+
17+
def execute(self, test, litConfig):
18+
if test.getSourcePath().endswith('.cpp') and not 'AVRLIT_PORT' in os.environ:
19+
return (lit.Test.UNSUPPORTED, 'AVRLIT_PORT environment variable is not set')
20+
21+
return ShTest.execute(self, test, litConfig)
22+
23+
24+
config.test_format = AVRCodeGenTest()
625

26+
# vim: filetype=python

utils/AVR/avrlit/CMakeLists.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
if (WIN32 AND NOT CYGWIN)
2+
# The script needs suffix.py for multiprocess to find a main module.
3+
set(suffix .py)
4+
endif ()
5+
6+
set(llvm_avrlit_path ${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-avrlit${suffix})
7+
8+
if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
9+
foreach(BUILD_MODE ${CMAKE_CONFIGURATION_TYPES})
10+
string(REPLACE ${CMAKE_CFG_INTDIR} ${BUILD_MODE} bi ${llvm_avrlit_path})
11+
configure_file(
12+
llvm-avrlit.in
13+
${bi}
14+
)
15+
endforeach()
16+
else()
17+
set(BUILD_MODE .)
18+
configure_file(
19+
llvm-avrlit.in
20+
${llvm_avrlit_path}
21+
)
22+
endif()

utils/AVR/avrlit/README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# AVR LLVM Integrated Tester
2+
3+
This tool builds an AVR executable from test code lowered by our backend and the
4+
`libavrlit` test suite library using a known good toolchain (avr-gcc). The
5+
resulting binary is uploaded to a development board. Test results are collected
6+
using a virtual tty.
7+
8+
### Setup
9+
10+
Things you will need:
11+
12+
* ATmega32U4 board with USB and AVR-109 type bootloader. (Arduino Leonardo,
13+
RedBear Blend (Micro), &c.)
14+
* [`pySerial`](http://pyserial.sourceforge.net) python module
15+
* avr-gcc
16+
* avrdude
17+
* GNU Make
18+
* Fire extinguisher
19+
20+
Set the `AVRLIT_PORT` environment variable to the tty path of your board.
21+
22+
```` bash
23+
> export AVRLIT_PORT=/dev/tty.usbmodemfd141
24+
````
25+
26+
If your board currently runs an Arduino sketch that uses the serial port, you are
27+
all set. Otherwise, you need to reset the board manually for the first run.
28+
29+
```` bash
30+
> bin/llvm-lit -v ../llvm/test/CodeGen/AVR/
31+
```
32+
33+
### Writing Tests
34+
35+
The on-target execution tests reside in `llvm/test/CodeGen/AVR`. Like other lit
36+
tests they contain a `RUN: ` line calling `llvm-avrlit`:
37+
38+
```` C++
39+
// RUN: llvm-avrlit %s %p/add.ll
40+
41+
#include <avrlit.h>
42+
43+
using namespace avrlit;
44+
45+
extern "C" { // actually this is extern "IR" but Bjarne forgot.
46+
i8 add8_reg_reg(i8, i8);
47+
}
48+
49+
AVRLIT_TEST(llvm_avr) {
50+
reenter (this) { // don't worry about the coroutine
51+
plan(3);
52+
ok(_(add8_reg_reg( 23, 42) == 23 + 42)); yield;
53+
ok(_(add8_reg_reg(-23, 42) == -23 + 42)); yield;
54+
ok(_(add8_reg_reg(-23, 42) == 0)); yield;
55+
}
56+
}
57+
````
58+
59+
All of this is still in flux. I'll explain it if I decide to keep it. ;)
60+
61+

utils/AVR/avrlit/libavrlit/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
all:
2+
$(MAKE) -C leonardo
3+
4+
5+
clean:
6+
$(MAKE) -C leonardo clean
7+

utils/AVR/avrlit/libavrlit/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# AVR LLVM Integrated Tester
2+
3+
This directory contains the sources of `libavrlit`, a test suite library to
4+
test code generated by our backend on the target. It uses the
5+
[LUFA USB library](http://www.fourwalledcubicle.com/LUFA.php)
6+
([GitHub](https://github.com/abcminiuser/lufa)) and its makefiles. This library
7+
and the test executbale are compiled using avr-gcc.
8+
9+
The test executables built with this framework connect to the host as a USB CDC
10+
device. They wait for the terminal to become ready before executing the tests. Results
11+
are printed in a format similar to `llvm-lit`.
12+
13+
### Installation
14+
15+
To avoid clutter the current library binary is checked in. To build the library
16+
the LUFA library is required:
17+
18+
````
19+
> git clone https://github.com/abcminiuser/lufa.git
20+
> make
21+
````
22+

0 commit comments

Comments
 (0)