Files
tms-c-compiler/scripts/tests/m3/layout.sh
T

93 lines
3.5 KiB
Bash
Executable File

#!/bin/sh
# M3 layout gate: Display.screens and Screen.root must be at the ROM's bit
# displacements 0x480 and 0x40.
#
# The ROM's indirect displacements are *bit* offsets (TMS34010), so those
# displacements are byte offsets 0x90 and 0x8. layout.c asserts the byte
# layout and returns the bit displacements; layout-ti.c does the same through
# the 1987 compiler's bit-addressed &-of-member. Both asm files must carry
# 0x480 / 0x40 (480h, 1152, ...).
set -eu
ROOT=$(cd "$(dirname "$0")/../../.." && pwd)
LLVM_BIN=${LLVM_BIN:-$ROOT/build/llvm-clean-build/bin}
TMS_CLANG=${TMS_CLANG:-$LLVM_BIN/clang}
TMS_OPT=${TMS_OPT:-$LLVM_BIN/opt}
TMS_LLC=${TMS_LLC:-$LLVM_BIN/llc}
TMS_BITADDR=${TMS_BITADDR:-$ROOT/tools/tms-bitaddr/tms-bitaddr}
WORK=${M3_LAYOUT_WORK:-$ROOT/build/m3-layout}
GOLDEN=$ROOT/scripts/m3/layout-ti.s
fail() {
echo "layout.sh: FAIL: $*" >&2
exit 1
}
for tool in "$TMS_CLANG" "$TMS_OPT" "$TMS_LLC" "$TMS_BITADDR"; do
[ -x "$tool" ] || fail "missing tool: $tool"
done
[ -f "$GOLDEN" ] || fail "missing TI golden: $GOLDEN"
mkdir -p "$WORK"
# Exit 0 here means the _Static_asserts in layout.c held on the target.
TMS_CLANG="$TMS_CLANG" TMS_OPT="$TMS_OPT" TMS_BITADDR="$TMS_BITADDR" \
"$ROOT/scripts/tms-clang" -O0 -o "$WORK/layout.ll" \
"$ROOT/scripts/m3/layout.c" \
|| fail "target compile failed (Display/Screen static asserts?)"
"$TMS_LLC" -march=tms34010 -O0 -filetype=asm \
"$WORK/layout.ll" -o "$WORK/layout.s" \
|| fail "llc failed for layout.ll"
# Print the body of one function, from its label to the next .globl/.end.
body() { # body FILE FUNC
awk -v want="_$2:" '
$1 == want { infn = 1; next }
infn && ($1 == ".globl" || $1 == ".end") { exit }
infn { print }
' "$1"
}
# Allowed spellings for a constant: C hex, assembler hex with `h`, decimal.
has_const() { # has_const FILE FUNC ERE
body "$1" "$2" | tr 'A-Z' 'a-z' | grep -Eq "$3"
}
check() { # check FILE FUNC ERE WHAT
if ! has_const "$1" "$2" "$3"; then
echo "layout.sh: $1: _$2 body:" >&2
body "$1" "$2" >&2
fail "_$2 in $1 does not contain $4"
fi
}
HEX480='(0x480|480h|[^0-9a-f]1152[^0-9a-f])'
HEX40='(0x40|40h|[^0-9a-f]64[^0-9a-f])'
check "$WORK/layout.s" layout_screens "$HEX480" "0x480 (Display.screens)"
check "$WORK/layout.s" layout_root "$HEX40" "0x40 (Screen.root)"
check "$GOLDEN" layout_screens "$HEX480" "0x480 (Display.screens)"
check "$GOLDEN" layout_root "$HEX40" "0x40 (Screen.root)"
# root_probe exercises the real access path: vt1200_root() follows
# Display.screens (bit 0x480) and reads Screen.root (bit 0x40). The helper is
# always_inline, so the incoming align-1 loads select MOVE directly in
# root_probe (see m3-unaligned.ll). Require both displacements and reject a
# MOVB byte split.
check "$WORK/layout.s" root_probe "$HEX480" "0x480 (Display.screens)"
check "$WORK/layout.s" root_probe "$HEX40" "0x40 (Screen.root)"
if body "$WORK/layout.s" root_probe | grep -q 'MOVB'; then
fail "root_probe contains MOVB: align-1 field loads did not select MOVE"
fi
# Guard against the old byte-pad mistake: 0x480*8 / 0x40*8 (9216 / 512)
# means the struct was padded in bytes past the ROM's bit displacements.
if body "$GOLDEN" layout_screens | tr 'A-Z' 'a-z' |
grep -Eq '(^|[^0-9])(9216|2400h)([^0-9a-f]|$)' ||
body "$GOLDEN" layout_root | tr 'A-Z' 'a-z' |
grep -Eq '(^|[^0-9])(512|200h)([^0-9a-f]|$)'; then
fail "TI golden carries byte-pad offsets (9216/512); ROM displacements are bits 0x480/0x40"
fi
echo "layout.sh: PASS (Display.screens=0x480, Screen.root=0x40; target + TI golden)"