* lib/sim-defs.exp (run_sim_test): Delete the .o and .x files if a
[binutils-gdb.git] / sim / testsuite / lib / sim-defs.exp
1 # Simulator dejagnu utilities.
2
3 # Communicate simulator path from sim_init to sim_version.
4 # For some reason [board_info target sim] doesn't work in sim_version.
5 # [Presumubly because the target has been "popped" by then. Odd though.]
6 set sim_path "unknown-run"
7
8 # Initialize the testrun.
9 # Required by dejagnu.
10
11 proc sim_init { args } {
12 global sim_path
13 set sim_path [board_info target sim]
14 # Need to return an empty string (copied from GAS).
15 return ""
16 }
17
18 # Print the version of the simulator being tested.
19 # Required by dejagnu.
20
21 proc sim_version {} {
22 global sim_path
23 set version 0.5
24 clone_output "$sim_path $version\n"
25 }
26
27 # Cover function to target_compile.
28 # Copied from gdb_compile.
29
30 proc sim_compile { source dest type options } {
31 set result [target_compile $source $dest $type $options]
32 regsub "\[\r\n\]*$" "$result" "" result
33 regsub "^\[\r\n\]*" "$result" "" result
34 if { $result != "" } {
35 clone_output "sim compile output: $result"
36 }
37 return $result
38 }
39
40 # Run a program on the simulator.
41 # Required by dejagnu (at least ${tool}_run used to be).
42 #
43 # SIM_OPTS are options for the simulator.
44 # PROG_OPTS are options passed to the simulated program.
45 # At present REDIR must be "" or "> foo".
46 # OPTIONS is a list of options internal to this routine.
47 # This is modelled after target_compile. We want to be able to add new
48 # options without having to update all our users.
49 # Currently:
50 # env(foo)=val - set environment variable foo to val for this run
51 # timeout=val - set the timeout to val for this run
52 #
53 # The result is a list of two elements.
54 # The first is one of pass/fail/etc.
55 # The second is the program's output.
56 #
57 # This is different than the sim_load routine provided by
58 # dejagnu/config/sim.exp. It's not clear how to pass arguments to the
59 # simulator (not the simulated program, the simulator) with sim_load.
60
61 proc sim_run { prog sim_opts prog_opts redir options } {
62 global SIMFLAGS
63
64 # Set the default value of the timeout.
65 # FIXME: The timeout value we actually want is a function of
66 # host, target, and testcase.
67 set testcase_timeout [board_info target sim_time_limit]
68 if { "$testcase_timeout" == "" } {
69 set testcase_timeout [board_info host testcase_timeout]
70 }
71 if { "$testcase_timeout" == "" } {
72 set testcase_timeout 240 ;# 240 same as in dejagnu/config/sim.exp.
73 }
74
75 # Initial the environment we pass to the testcase.
76 set testcase_env ""
77
78 # Process OPTIONS ...
79 foreach o $options {
80 if [regexp {^env\((.*)\)=(.*)} $o full var val] {
81 set testcase_env "$testcase_env $var=$val"
82 } elseif [regexp {^timeout=(.*)} $o full val] {
83 set testcase_timeout $val
84 }
85
86 }
87
88 verbose "testcase timeout is set to $testcase_timeout" 1
89
90 set sim [board_info target sim]
91
92 if [is_remote host] {
93 set prog [remote_download host $prog]
94 if { $prog == "" } {
95 error "download failed"
96 return -1;
97 }
98 }
99
100 set board [target_info name]
101 if [board_info $board exists sim,options] {
102 set always_opts [board_info $board sim,options]
103 } else {
104 set always_opts ""
105 }
106
107 # FIXME: this works for UNIX only
108 if { "$testcase_env" != "" } {
109 set sim "env $testcase_env $sim"
110 }
111
112 send_log "$sim $always_opts $SIMFLAGS $sim_opts $prog $prog_opts\n"
113
114 if { "$redir" == "" } {
115 remote_spawn host "$sim $always_opts $SIMFLAGS $sim_opts $prog $prog_opts"
116 } else {
117 remote_spawn host "$sim $always_opts $SIMFLAGS $sim_opts $prog $prog_opts $redir" writeonly
118 }
119 set result [remote_wait host $testcase_timeout]
120
121 set return_code [lindex $result 0]
122 set output [lindex $result 1]
123 # Remove the \r part of "\r\n" so we don't break all the patterns
124 # we want to match.
125 regsub -all -- "\r" $output "" output
126
127 if [is_remote host] {
128 # clean up after ourselves.
129 remote_file host delete $prog
130 }
131
132 # ??? Not sure the test for pass/fail is right.
133 # We just care that the simulator ran correctly, not whether the simulated
134 # program return 0 or non-zero from `main'.
135 set status fail
136 if { $return_code == 0 } {
137 set status pass
138 }
139
140 return [list $status $output]
141 }
142
143 # Run testcase NAME.
144 # NAME is either a fully specified file name, or just the file name in which
145 # case $srcdir/$subdir will be prepended.
146 # REQUESTED_MACHS is a list of machines to run the testcase on. If NAME isn't
147 # for the specified machine(s), it is ignored.
148 # Typically REQUESTED_MACHS contains just one element, it is up to the caller
149 # to iterate over the desired machine variants.
150 #
151 # The file can contain options in the form "# option(mach list): value".
152 # Possibilities:
153 # mach: [all | machine names]
154 # as[(mach-list)]: <assembler options>
155 # ld[(mach-list)]: <linker options>
156 # sim[(mach-list)]: <simulator options>
157 # output: program output pattern to match with string-match
158 # xerror: program is expected to return with a "failure" exit code
159 # If `output' is not specified, the program must output "pass" if !xerror or
160 # "fail" if xerror.
161 # The parens in "optname()" are optional if the specification is for all machs.
162
163 proc run_sim_test { name requested_machs } {
164 global subdir srcdir
165 global SIMFLAGS
166 global opts
167 global cpu_option
168
169 if [string match "*/*" $name] {
170 set file $name
171 set name [file tail $name]
172 } else {
173 set file "$srcdir/$subdir/$name"
174 }
175
176 set opt_array [slurp_options "${file}"]
177 if { $opt_array == -1 } {
178 unresolved $subdir/$name
179 return
180 }
181 # Clear default options
182 set opts(as) ""
183 set opts(ld) ""
184 set opts(sim) ""
185 set opts(output) ""
186 set opts(mach) ""
187 set opts(timeout) ""
188 set opts(xerror) "no"
189
190 # Clear any machine specific options specified in a previous test case
191 foreach m $requested_machs {
192 if [info exists opts(as,$m)] {
193 unset opts(as,$m)
194 }
195 if [info exists opts(ld,$m)] {
196 unset opts(ld,$m)
197 }
198 if [info exists opts(sim,$m)] {
199 unset opts(sim,$m)
200 }
201 }
202
203 foreach i $opt_array {
204 set opt_name [lindex $i 0]
205 set opt_machs [lindex $i 1]
206 set opt_val [lindex $i 2]
207 if ![info exists opts($opt_name)] {
208 perror "unknown option $opt_name in file $file"
209 unresolved $subdir/$name
210 return
211 }
212 foreach m $opt_machs {
213 set opts($opt_name,$m) $opt_val
214 }
215 if { "$opt_machs" == "" } {
216 set opts($opt_name) $opt_val
217 }
218 }
219
220 set testname $name
221 set sourcefile $file
222 if { $opts(output) == "" } {
223 if { "$opts(xerror)" == "no" } {
224 set opts(output) "pass\n"
225 } else {
226 set opts(output) "fail\n"
227 }
228 }
229 # Change \n sequences to newline chars.
230 regsub -all "\\\\n" $opts(output) "\n" opts(output)
231
232 set testcase_machs $opts(mach)
233 if { "$testcase_machs" == "all" } {
234 set testcase_machs $requested_machs
235 }
236
237 foreach mach $testcase_machs {
238 if { [lsearch $requested_machs $mach] < 0 } {
239 verbose -log "Skipping $mach version of $name, not requested."
240 continue
241 }
242
243 verbose -log "Testing $name on machine $mach."
244
245 if ![info exists opts(as,$mach)] {
246 set opts(as,$mach) $opts(as)
247 }
248
249 set as_options "$opts(as,$mach) -I$srcdir/$subdir"
250 if [info exists cpu_option] {
251 set as_options "$as_options $cpu_option=$mach"
252 }
253 set comp_output [target_assemble $sourcefile ${name}.o "$as_options"]
254
255 if ![string match "" $comp_output] {
256 verbose -log "$comp_output" 3
257 fail "$mach $testname (assembling)"
258 continue
259 }
260
261 if ![info exists opts(ld,$mach)] {
262 set opts(ld,$mach) $opts(ld)
263 }
264
265 set comp_output [target_link ${name}.o ${name}.x "$opts(ld,$mach)"]
266
267 if ![string match "" $comp_output] {
268 verbose -log "$comp_output" 3
269 fail "$mach $testname (linking)"
270 continue
271 }
272
273 # If no machine specific options, default to the general version.
274 if ![info exists opts(sim,$mach)] {
275 set opts(sim,$mach) $opts(sim)
276 }
277
278 # Build the options argument.
279 set options ""
280 if { "$opts(timeout)" != "" } {
281 set options "$options timeout=$opts(timeout)"
282 }
283
284 set result [sim_run ${name}.x "$opts(sim,$mach)" "" "" "$options"]
285 set status [lindex $result 0]
286 set output [lindex $result 1]
287
288 if { "$status" == "pass" } {
289 if { "$opts(xerror)" == "no" } {
290 if [string match $opts(output) $output] {
291 pass "$mach $testname"
292 file delete ${name}.o ${name}.x
293 } else {
294 verbose -log "output: $output" 3
295 verbose -log "pattern: $opts(output)" 3
296 fail "$mach $testname (execution)"
297 }
298 } else {
299 verbose -log "`pass' return code when expecting failure" 3
300 fail "$mach $testname (execution)"
301 }
302 } elseif { "$status" == "fail" } {
303 if { "$opts(xerror)" == "no" } {
304 fail "$mach $testname (execution)"
305 } else {
306 if [string match $opts(output) $output] {
307 pass "$mach $testname"
308 file delete ${name}.o ${name}.x
309 } else {
310 verbose -log "output: $output" 3
311 verbose -log "pattern: $opts(output)" 3
312 fail "$mach $testname (execution)"
313 }
314 }
315 } else {
316 $status "$mach $testname"
317 }
318 }
319 }
320
321 # Subroutine of run_sim_test to process options in FILE.
322
323 proc slurp_options { file } {
324 if [catch { set f [open $file r] } x] {
325 #perror "couldn't open `$file': $x"
326 perror "$x"
327 return -1
328 }
329 set opt_array {}
330 # whitespace expression
331 set ws {[ ]*}
332 set nws {[^ ]*}
333 # whitespace is ignored anywhere except within the options list;
334 # option names are alphabetic only
335 set pat "^#${ws}(\[a-zA-Z\]*)\\(?(\[^):\]*)\\)?$ws:${ws}(.*)$ws\$"
336 # Allow arbitrary lines until the first option is seen.
337 set seen_opt 0
338 while { [gets $f line] != -1 } {
339 set line [string trim $line]
340 # Whitespace here is space-tab.
341 if [regexp $pat $line xxx opt_name opt_machs opt_val] {
342 # match!
343 lappend opt_array [list $opt_name $opt_machs $opt_val]
344 set seen_opt 1
345 } else {
346 if { $seen_opt } {
347 break
348 }
349 }
350 }
351 close $f
352 return $opt_array
353 }