93 lines
3.5 KiB
Bash
Executable File
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)"
|