seed/update 5.3 KiB raw
1
#!/bin/sh
2
#
3
# Find the compiler fixed point and update the seed binary.
4
#
5
# Iterates self-compilation stages starting from the current seed until a fixed
6
# point is reached, then copies the result back to the seed.
7
#
8
# Usage: seed/update [--seed <path>] [--from-s0]
9
#
10
# Options:
11
#   --seed <path>            Use <path> as the seed binary instead of seed/radiance.rv64
12
#   --from-s0                Run the seed as a native binary (stage 0) instead of
13
#                            through the emulator
14
#
15
# Environment variables:
16
#   EMULATOR_MEMORY_SIZE     Emulator memory in KB (default: 385024)
17
#   EMULATOR_DATA_SIZE       Emulator data segment in KB (default: 348160)
18
#
19
set -eu
20
21
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
22
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
23
24
cd "${ROOT_DIR}"
25
26
# ---------------------------------------------------------------------------
27
# Helpers
28
# ---------------------------------------------------------------------------
29
30
step() {
31
  printf "\n==> %s\n" "$*"
32
}
33
34
fail() {
35
  printf "!! %s\n" "$*" >&2
36
  exit 1
37
}
38
39
# ---------------------------------------------------------------------------
40
# Command line flags for Radiance compiler
41
# ---------------------------------------------------------------------------
42
43
STD_MODS="$(sed 's/^/-mod /' std.lib | tr '\n' ' ')"
44
OPTS="-pkg std ${STD_MODS} -pkg radiance -mod compiler/radiance.rad -entry radiance"
45
46
# ---------------------------------------------------------------------------
47
# Emulator settings
48
# ---------------------------------------------------------------------------
49
50
MEMORY_SIZE="${EMULATOR_MEMORY_SIZE:-385024}"
51
DATA_SIZE="${EMULATOR_DATA_SIZE:-348160}"
52
EMU="${RAD_EMULATOR:-emulator} -debug -no-validate \
53
    -memory-size=${MEMORY_SIZE} -data-size=${DATA_SIZE} \
54
    -count-instructions -run"
55
56
# ---------------------------------------------------------------------------
57
# Compile one self-hosted stage.
58
#   stage <input> <output>
59
# ---------------------------------------------------------------------------
60
61
stage() {
62
  time $EMU "$1" $OPTS -o "$2"
63
}
64
65
# ---------------------------------------------------------------------------
66
# Compile one stage using a native (s0) binary.
67
#   stageS0 <input> <output>
68
# ---------------------------------------------------------------------------
69
70
stageS0() {
71
  time "$1" compiler/radiance.rad $OPTS -o "$2"
72
}
73
74
# ---------------------------------------------------------------------------
75
# Compare two stage binaries. Returns 0 if identical, 1 if they differ.
76
# ---------------------------------------------------------------------------
77
78
compareStages() {
79
  if cmp -s "$1" "$2" \
80
  && cmp -s "$1.ro.data" "$2.ro.data" \
81
  && cmp -s "$1.rw.data" "$2.rw.data"; then
82
    printf " IDENTICAL\n  sha256: %s\n" "$(sha256sum "$2" | cut -d' ' -f1)"
83
    return 0
84
  else
85
    printf " DIFFERENT\n"
86
    return 1
87
  fi
88
}
89
90
# ---------------------------------------------------------------------------
91
# Copy the fixed-point binary to the seed.
92
# ---------------------------------------------------------------------------
93
94
updateSeed() {
95
  [ "$1"         != seed/radiance.rv64 ]         && cp "$1"         seed/radiance.rv64
96
  [ "$1.ro.data" != seed/radiance.rv64.ro.data ] && cp "$1.ro.data" seed/radiance.rv64.ro.data
97
  [ "$1.rw.data" != seed/radiance.rv64.rw.data ] && cp "$1.rw.data" seed/radiance.rv64.rw.data
98
99
  git rev-parse HEAD > seed/radiance.rv64.git
100
101
  printf "\n"
102
  printf "Fixed point reached at %s\n" "$2"
103
  printf "Seed updated (commit $(git rev-parse --short HEAD))\n"
104
}
105
106
# ---------------------------------------------------------------------------
107
# Parse arguments
108
# ---------------------------------------------------------------------------
109
110
SEED="seed/radiance.rv64"
111
FROM_S0=0
112
113
while [ $# -gt 0 ]; do
114
  case "$1" in
115
    --seed)
116
      [ $# -ge 2 ] || fail "--seed requires an argument"
117
      SEED="$(realpath "$2")"
118
      shift 2
119
      ;;
120
    --from-s0)
121
      FROM_S0=1
122
      shift
123
      ;;
124
    *)
125
      fail "unknown option: $1"
126
      ;;
127
  esac
128
done
129
130
command -v "${RAD_EMULATOR:-emulator}" >/dev/null 2>&1 \
131
  || fail "emulator not found: set RAD_EMULATOR or add 'emulator' to PATH"
132
[ -f "${SEED}" ] || fail "seed binary not found: ${SEED}"
133
134
# ---------------------------------------------------------------------------
135
# Stage 1: seed compiles source
136
# ---------------------------------------------------------------------------
137
138
S1=seed/radiance.rv64.s1
139
S2=seed/radiance.rv64.s2
140
S3=seed/radiance.rv64.s3
141
S4=seed/radiance.rv64.s4
142
143
step "Stage 1: S0 builds S1"
144
if [ "${FROM_S0}" -eq 1 ]; then
145
  stageS0 "${SEED}" "${S1}"
146
else
147
  stage "${SEED}" "${S1}"
148
fi
149
150
printf "\nComparing S0 and S1 ..."
151
if compareStages "${SEED}" "${S1}"; then
152
  updateSeed "${SEED}" "S0"
153
  exit 0
154
fi
155
156
# ---------------------------------------------------------------------------
157
# Stage 2: S1 compiles source
158
# ---------------------------------------------------------------------------
159
160
step "Stage 2: S1 builds S2"
161
stage "${S1}" "${S2}"
162
163
printf "\nComparing S1 and S2 ..."
164
if compareStages "${S1}" "${S2}"; then
165
  updateSeed "${S1}" "S1"
166
  exit 0
167
fi
168
169
# ---------------------------------------------------------------------------
170
# Stage 3: S2 compiles source
171
# ---------------------------------------------------------------------------
172
173
step "Stage 3: S2 builds S3"
174
stage "${S2}" "${S3}"
175
176
printf "\nComparing S2 and S3 ..."
177
if compareStages "${S2}" "${S3}"; then
178
  updateSeed "${S2}" "S2"
179
  exit 0
180
fi
181
182
fail "No fixed point reached after 3 stages"