[PATCH 7/57][Arm][GAS] Add support for MVE instructions: vstr/vldr
[binutils-gdb.git] / gdb / testsuite / gdb.arch / mips16-thunks.exp
blob8f0b993f3e3c344925859bd1901fa81bc0a836f9
1 # Copyright 2012-2019 Free Software Foundation, Inc.
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 # Contributed by Mentor Graphics, written by Maciej W. Rozycki.
18 # Test MIPS16 thunk support.
20 # This should work on any targets that support MIPS16 execution, including
21 # Linux and bare-iron ones, but not all of them do, for example MIPS16
22 # support has been added to Linux relatively late in the game.  Also besides
23 # environment support, the target processor has to support the MIPS16 ASE.
24 # Finally as of this writing MIPS16 support has only been implemented in the
25 # toolchain for a subset of ABIs, so we need to check that a MIPS16
26 # executable can be built and run at all before we attempt the actual test.
28 if { ![istarget "mips*-*-*"] } then {
29     verbose "Skipping MIPS16 thunk support tests."
30     return
33 # A helper to set caller's SRCFILE and OBJFILE based on FILENAME and SUFFIX.
34 proc set_src_and_obj { filename { suffix "" } } {
35     upvar srcfile srcfile
36     upvar objfile objfile
37     global srcdir
38     global subdir
40     if ![string equal "$suffix" ""] then {
41         set suffix "-$suffix"
42     }
43     set srcfile ${srcdir}/${subdir}/${filename}.c
44     set objfile [standard_output_file ${filename}${suffix}.o]
47 # First check if a trivial MIPS16 program can be built and debugged.  This
48 # verifies environment and processor support, any failure here must be
49 # classed as the lack of support.
50 set testname mips16-thunks-main
52 set_src_and_obj mips16-thunks-inmain
53 set options [list debug nowarnings additional_flags=-mips16]
54 set objfiles ${objfile}
55 gdb_compile ${srcfile} ${objfile} object ${options}
57 set_src_and_obj mips16-thunks-main
58 set options [list debug nowarnings additional_flags=-mips16]
59 lappend objfiles ${objfile}
60 gdb_compile ${srcfile} ${objfile} object ${options}
62 set binfile [standard_output_file ${testname}]
63 set options [list debug nowarnings]
64 if { [gdb_compile ${objfiles} ${binfile} executable ${options}] != "" } then {
65     unsupported "no MIPS16 support in the toolchain."
66     return
68 clean_restart ${testname}
69 gdb_breakpoint inmain
70 gdb_run_cmd
71 gdb_test_multiple "" "check for MIPS16 support in the processor" {
72     -re "Breakpoint 1.*inmain .*$gdb_prompt $" {
73         gdb_test_multiple "finish" \
74             "check for MIPS16 support in the processor" {
75             -re "Value returned is \\\$\[0-9\]+ = 0\[^0-9\].*$gdb_prompt $" {
76                 verbose "MIPS16 support check successful."
77             }
78             -re "$gdb_prompt $" {
79                 unsupported "no MIPS16 support in the processor."
80                 return
81             }
82             default {
83                 unsupported "no MIPS16 support in the processor."
84                 return
85             }
86         }
87     }
88     -re "$gdb_prompt $" {
89         unsupported "no MIPS16 support in the processor."
90         return
91     }
92     default {
93         unsupported "no MIPS16 support in the processor."
94         return
95     }
98 # Check if MIPS16 PIC code can be built and debugged.  We want to check
99 # PIC and MIPS16 thunks are handled correctly together if possible, but
100 # on targets that do not support PIC code, e.g. bare iron, we still want
101 # to test the rest of functionality.
102 set testname mips16-thunks-pic
103 set picflag ""
105 set_src_and_obj mips16-thunks-inmain pic
106 set options [list \
107     debug nowarnings additional_flags=-mips16 additional_flags=-fPIC]
108 set objfiles ${objfile}
109 gdb_compile ${srcfile} ${objfile} object ${options}
111 set_src_and_obj mips16-thunks-main pic
112 set options [list \
113     debug nowarnings additional_flags=-mips16 additional_flags=-fPIC]
114 lappend objfiles ${objfile}
115 gdb_compile ${srcfile} ${objfile} object ${options}
117 set binfile [standard_output_file ${testname}]
118 set options [list debug nowarnings additional_flags=-fPIC]
119 if { [gdb_compile ${objfiles} ${binfile} executable ${options}] == "" } then {
120     clean_restart ${testname}
121     gdb_breakpoint inmain
122     gdb_run_cmd
123     gdb_test_multiple "" "check for PIC support" {
124         -re "Breakpoint 1.*inmain .*$gdb_prompt $" {
125             note "PIC support present, will make additional PIC thunk checks."
126             set picflag additional_flags=-fPIC
127         }
128         -re "$gdb_prompt $" {
129             note "No PIC support, skipping additional PIC thunk checks."
130         }
131         default {
132             note "No PIC support, skipping additional PIC thunk checks."
133         }
134     }
135 } else {
136     note "No PIC support, skipping additional PIC thunk checks."
139 # OK, build the twisted executable.  This program contains the following
140 # MIPS16 thunks:
141 # - __call_stub_fp_sin,
142 # - __call_stub_fp_sinblah,
143 # - __call_stub_fp_sinfrob,
144 # - __call_stub_fp_sinhelper,
145 # - __call_stub_lsinhelper,
146 # - __fn_stub_lsinmips16,
147 # - __fn_stub_sinblah16,
148 # - __fn_stub_sinfrob16,
149 # - __fn_stub_sinmips16,
150 # - __mips16_call_stub_df_2,
151 # - __mips16_ret_df.
152 # Additionally, if PIC code is supported, it contains the following PIC thunks:
153 # - .pic.__mips16_call_stub_df_2,
154 # - .pic.__mips16_ret_df,
155 # - .pic.sinblah,
156 # - .pic.sinblah16,
157 # - .pic.sinfrob,
158 # - .pic.sinfrob16.
159 set testname mips16-thunks-sin
161 set_src_and_obj mips16-thunks-sinmain
162 set options [list debug nowarnings additional_flags=-mips16]
163 set objfiles ${objfile}
164 gdb_compile ${srcfile} ${objfile} object ${options}
166 set_src_and_obj mips16-thunks-sin
167 set options [list debug nowarnings additional_flags=-mno-mips16]
168 lappend objfiles ${objfile}
169 gdb_compile ${srcfile} ${objfile} object ${options}
171 set_src_and_obj mips16-thunks-sinmips16
172 set options [list debug nowarnings additional_flags=-mips16]
173 lappend objfiles ${objfile}
174 gdb_compile ${srcfile} ${objfile} object ${options}
176 set_src_and_obj mips16-thunks-sinfrob
177 set options [list \
178     debug nowarnings additional_flags=-mno-mips16 ${picflag}]
179 lappend objfiles ${objfile}
180 gdb_compile ${srcfile} ${objfile} object ${options}
182 set_src_and_obj mips16-thunks-sinfrob16
183 set options [list \
184     debug nowarnings additional_flags=-mips16 ${picflag}]
185 lappend objfiles ${objfile}
186 gdb_compile ${srcfile} ${objfile} object ${options}
188 set binfile [standard_output_file ${testname}]
189 set options [list debug nowarnings]
190 gdb_compile ${objfiles} ${binfile} executable ${options}
191 clean_restart ${testname}
192 if ![runto_main] then {
193     fail "running test program, MIPS16 thunk tests aborted"
194     return
197 # Build some useful regular expressions out of a list of functions FUNCS
198 # to be used to match against backtraces.
199 proc build_frames_re { funcs } {
200     upvar anyframe anyframe
201     upvar frames frames
202     upvar frame frame
203     upvar func func
205     set fid 0
206     set argsandsource " +\\\(.*\\\) +at +\[^\r\n\]+\r\n"
207     set addrin "(?:\[^ \]+ +in +)?"
208     set anyframe "#${fid} +${addrin}(\[^ \]+)${argsandsource}"
209     set frame "#${fid} +${addrin}${func}${argsandsource}"
210     set frames "$frame"
211     foreach f [lrange $funcs 1 end] {
212         incr fid
213         append frames "#${fid} +${addrin}${f}${argsandsource}"
214     }
217 # Single-step through the function that is at the head of function list
218 # FUNCS until a different function (frame) is reached.  Before each step
219 # check the backtrace against FUNCS.  ID is used for reporting, to tell
220 # apart different calls to this procedure for the same function.  If
221 # successful, then return the name of the function we have stopped in.
222 proc step_through { id funcs } {
223     global gdb_prompt
225     set func [lindex $funcs 0]
226     build_frames_re "$funcs"
228     set msg "single-stepping through \"${func}\" ($id)"
230     # Arbitrarily limit the maximium number of steps made to avoid looping
231     # indefinitely in the case something goes wrong, increase as (if)
232     # necessary.
233     set count 8
234     while { $count > 0 } {
235         if { [gdb_test_multiple "backtrace" "$msg (backtrace)" {
236             -re "${frames}$gdb_prompt $" {
237                 if { [gdb_test_multiple "step" "$msg (step)" {
238                     -re "$gdb_prompt $" {
239                         if { [gdb_test_multiple "frame" "$msg (frame)" {
240                             -re "${frame}.*$gdb_prompt $" {
241                             }
242                             -re "${anyframe}.*$gdb_prompt $" {
243                                 pass "$msg"
244                                 return $expect_out(1,string)
245                             }
246                         }] != 0 } then {
247                             return ""
248                         }
249                     }
250                 }] != 0 } then {
251                     return ""
252                 }
253             }
254         }] != 0 } then {
255             return ""
256         }
257         incr count -1
258     }
259     fail "$msg (too many steps)"
260     return ""
263 # Finish the current function that must be one that is at the head of
264 # function list FUNCS.  Before that check the backtrace against FUNCS.
265 # ID is used for reporting, to tell apart different calls to this
266 # procedure for the same function.  If successful, then return the name
267 # of the function we have stopped in.
268 proc finish_through { id funcs } {
269     global gdb_prompt
271     set func [lindex $funcs 0]
272     build_frames_re "$funcs"
274     set msg "finishing \"${func}\" ($id)"
276     gdb_test_multiple "backtrace" "$msg (backtrace)" {
277         -re "${frames}$gdb_prompt $" {
278             gdb_test_multiple "finish" "$msg (finish)" {
279                 -re "Run till exit from ${frame}.*$gdb_prompt $" {
280                     gdb_test_multiple "frame" "$msg (frame)" {
281                         -re "${anyframe}.*$gdb_prompt $" {
282                             pass "$msg"
283                             return $expect_out(1,string)
284                         }
285                     }
286                 }
287             }
288         }
289     }
290     return ""
293 # Report PASS if VAL is equal to EXP, otherwise report FAIL, using MSG.
294 proc pass_if_eq { val exp msg } {
295     if [string equal "$val" "$exp"] then {
296         pass "$msg"
297     } else {
298         fail "$msg"
299     }
302 # Check if FUNC is equal to WANT.  If not, then assume that we have stepped
303 # into a library call.  In this case finish it, then step out of the caller.
304 # ID is used for reporting, to tell apart different calls to this procedure
305 # for the same function.  If successful, then return the name of the
306 # function we have stopped in.
307 proc finish_if_ne { id func want funcs } {
308     if ![string equal "$func" "$want"] then {
309         set call "$func"
310         set want [lindex $funcs 0]
311         set func [finish_through "$id" [linsert $funcs 0 "$func"]]
312         pass_if_eq "$func" "$want" "\"${call}\" finishing to \"${want}\" ($id)"
313         set func [step_through "$id" $funcs]
314     }
315     return "$func"
318 # Now single-step through the program, making sure all thunks are correctly
319 # stepped over and omitted from backtraces.
321 set id 1
322 set func [step_through $id [list main]]
323 pass_if_eq "$func" sinfrob16 "stepping from \"main\" into \"sinfrob16\" ($id)"
325 incr id
326 set func [step_through $id [list sinfrob16 main]]
327 set func [finish_if_ne $id "$func" main [list sinfrob16 main]]
328 pass_if_eq "$func" main "stepping from \"sinfrob16\" back to \"main\" ($id)"
330 incr id
331 set func [step_through $id [list main]]
332 pass_if_eq "$func" sinfrob "stepping from \"main\" into \"sinfrob\" ($id)"
334 incr id
335 set func [step_through $id [list sinfrob main]]
336 set func [finish_if_ne $id "$func" main [list sinfrob main]]
337 pass_if_eq "$func" main "stepping from \"sinfrob\" back to \"main\" ($id)"
339 # 5
340 incr id
341 set func [step_through $id [list main]]
342 pass_if_eq "$func" sinhelper "stepping from \"main\" into \"sinhelper\" ($id)"
344 incr id
345 set func [step_through $id [list sinhelper main]]
346 set func [finish_if_ne $id "$func" sinfrob16 [list sinhelper main]]
347 pass_if_eq "$func" sinfrob16 \
348     "stepping from \"sinhelper\" into \"sinfrob16\" ($id)"
350 incr id
351 set func [step_through $id [list sinfrob16 sinhelper main]]
352 set func [finish_if_ne $id "$func" sinhelper [list sinfrob16 sinhelper main]]
353 pass_if_eq "$func" sinhelper \
354     "stepping from \"sinfrob16\" back to \"sinhelper\" ($id)"
356 incr id
357 set func [step_through $id [list sinhelper main]]
358 pass_if_eq "$func" sinfrob "stepping from \"sinhelper\" into \"sinfrob\" ($id)"
360 incr id
361 set func [step_through $id [list sinfrob sinhelper main]]
362 set func [finish_if_ne $id "$func" sinhelper [list sinfrob sinhelper main]]
363 pass_if_eq "$func" sinhelper \
364     "stepping from \"sinfrob\" back to \"sinhelper\" ($id)"
366 # 10
367 incr id
368 set func [step_through $id [list sinhelper main]]
369 pass_if_eq "$func" sinmips16 \
370     "stepping from \"sinhelper\" into \"sinmips16\" ($id)"
372 incr id
373 set func [step_through $id [list sinmips16 sinhelper main]]
374 set func [finish_if_ne $id "$func" sinfrob16 [list sinmips16 sinhelper main]]
375 pass_if_eq "$func" sinfrob16 \
376     "stepping from \"sinmips16\" into \"sinfrob16\" ($id)"
378 incr id
379 set func [step_through $id [list sinfrob16 sinmips16 sinhelper main]]
380 set func [finish_if_ne $id "$func" sinmips16 \
381               [list sinfrob16 sinmips16 sinhelper main]]
382 pass_if_eq "$func" sinmips16 \
383     "stepping from \"sinfrob16\" back to \"sinmips16\" ($id)"
385 incr id
386 set func [step_through $id [list sinmips16 sinhelper main]]
387 pass_if_eq "$func" sinfrob "stepping from \"sinmips16\" into \"sinfrob\" ($id)"
389 incr id
390 set func [step_through $id [list sinfrob sinmips16 sinhelper main]]
391 set func [finish_if_ne $id "$func" sinhelper \
392               [list sinfrob sinmips16 sinhelper main]]
393 pass_if_eq "$func" sinmips16 \
394     "stepping from \"sinfrob\" back to \"sinmips16\" ($id)"
396 # 15
397 incr id
398 set func [step_through $id [list sinmips16 sinhelper main]]
399 pass_if_eq "$func" sinfrob16 \
400     "stepping from \"sinmips16\" into \"sinfrob16\" (indirectly) ($id)"
402 incr id
403 set func [step_through $id [list sinfrob16 sinmips16 sinhelper main]]
404 set func [finish_if_ne $id "$func" sinmips16 \
405               [list sinfrob16 sinmips16 sinhelper main]]
406 pass_if_eq "$func" sinmips16 \
407     "stepping from \"sinfrob16\" back to \"sinmips16\" (indirectly) ($id)"
409 incr id
410 set func [step_through $id [list sinmips16 sinhelper main]]
411 pass_if_eq "$func" sinfrob \
412     "stepping from \"sinmips16\" into \"sinfrob\" (indirectly) ($id)"
414 incr id
415 set func [step_through $id [list sinfrob sinmips16 sinhelper main]]
416 set func [finish_if_ne $id "$func" sinhelper \
417               [list sinfrob sinmips16 sinhelper main]]
418 pass_if_eq "$func" sinmips16 \
419     "stepping from \"sinfrob\" back to \"sinmips16\" (indirectly) ($id)"
421 incr id
422 set func [step_through $id [list sinmips16 sinhelper main]]
423 pass_if_eq "$func" sinhelper \
424     "stepping from \"sinmips16\" back to \"sinhelper\" ($id)"
426 # 20
427 incr id
428 set func [step_through $id [list sinhelper main]]
429 pass_if_eq "$func" main "stepping from \"sinhelper\" back to \"main\" ($id)"
431 incr id
432 set func [step_through $id [list main]]
433 pass_if_eq "$func" sinblah "stepping from \"main\" into \"sinblah\" ($id)"
435 incr id
436 set func [step_through $id [list sinblah main]]
437 set func [finish_if_ne $id "$func" main [list sinblah main]]
438 pass_if_eq "$func" main "stepping from \"sinblah\" back to \"main\" ($id)"
440 incr id
441 set func [step_through $id [list main]]
442 pass_if_eq "$func" sinblah16 "stepping from \"main\" into \"sinblah16\" ($id)"
444 incr id
445 set func [step_through $id [list sinblah16 main]]
446 set func [finish_if_ne $id "$func" main [list sinblah16 main]]
447 pass_if_eq "$func" main "stepping from \"sinblah16\" back to \"main\" ($id)"
449 # 25
450 incr id
451 set func [step_through $id [list main]]
452 pass_if_eq "$func" lsinhelper \
453     "stepping from \"main\" into \"lsinhelper\" ($id)"
455 incr id
456 set func [step_through $id [list lsinhelper main]]
457 set func [finish_if_ne $id "$func" sinblah [list lsinhelper main]]
458 pass_if_eq "$func" sinblah \
459     "stepping from \"lsinhelper\" into \"sinblah\" ($id)"
461 incr id
462 set func [step_through $id [list sinblah lsinhelper main]]
463 set func [finish_if_ne $id "$func" lsinhelper [list sinblah lsinhelper main]]
464 pass_if_eq "$func" lsinhelper \
465     "stepping from \"sinblah\" back to \"lsinhelper\" ($id)"
467 incr id
468 set func [step_through $id [list lsinhelper main]]
469 pass_if_eq "$func" sinblah16 \
470     "stepping from \"lsinhelper\" into \"sinblah16\" ($id)"
472 incr id
473 set func [step_through $id [list sinblah16 lsinhelper main]]
474 set func [finish_if_ne $id "$func" lsinhelper [list sinblah16 lsinhelper main]]
475 pass_if_eq "$func" lsinhelper \
476     "stepping from \"sinblah16\" back to \"lsinhelper\" ($id)"
478 # 30
479 incr id
480 set func [step_through $id [list lsinhelper main]]
481 pass_if_eq "$func" lsinmips16 \
482     "stepping from \"lsinhelper\" into \"lsinmips16\" ($id)"
484 incr id
485 set func [step_through $id [list lsinmips16 lsinhelper main]]
486 set func [finish_if_ne $id "$func" sinblah [list lsinmips16 lsinhelper main]]
487 pass_if_eq "$func" sinblah \
488     "stepping from \"lsinmips16\" into \"sinblah\" ($id)"
490 incr id
491 set func [step_through $id [list sinblah lsinmips16 lsinhelper main]]
492 set func [finish_if_ne $id "$func" lsinmips16 \
493               [list sinblah lsinmips16 lsinhelper main]]
494 pass_if_eq "$func" lsinmips16 \
495     "stepping from \"sinblah\" back to \"lsinmips16\" ($id)"
497 incr id
498 set func [step_through $id [list lsinmips16 lsinhelper main]]
499 pass_if_eq "$func" sinblah16 \
500     "stepping from \"lsinmips16\" into \"sinblah16\" ($id)"
502 incr id
503 set func [step_through $id [list sinblah16 lsinmips16 lsinhelper main]]
504 set func [finish_if_ne $id "$func" lsinhelper \
505               [list sinblah16 lsinmips16 lsinhelper main]]
506 pass_if_eq "$func" lsinmips16 \
507     "stepping from \"sinblah16\" back to \"lsinmips16\" ($id)"
509 # 35
510 incr id
511 set func [step_through $id [list lsinmips16 lsinhelper main]]
512 pass_if_eq "$func" sinblah \
513     "stepping from \"lsinmips16\" into \"sinblah\" (indirectly) ($id)"
515 incr id
516 set func [step_through $id [list sinblah lsinmips16 lsinhelper main]]
517 set func [finish_if_ne $id "$func" lsinmips16 \
518               [list sinblah lsinmips16 lsinhelper main]]
519 pass_if_eq "$func" lsinmips16 \
520     "stepping from \"sinblah\" back to \"lsinmips16\" (indirectly) ($id)"
522 incr id
523 set func [step_through $id [list lsinmips16 lsinhelper main]]
524 pass_if_eq "$func" sinblah16 \
525     "stepping from \"lsinmips16\" into \"sinblah16\" (indirectly) ($id)"
527 incr id
528 set func [step_through $id [list sinblah16 lsinmips16 lsinhelper main]]
529 set func [finish_if_ne $id "$func" lsinhelper \
530               [list sinblah16 lsinmips16 lsinhelper main]]
531 pass_if_eq "$func" lsinmips16 \
532     "stepping from \"sinblah16\" back to \"lsinmips16\" (indirectly) ($id)"
534 incr id
535 set func [step_through $id [list lsinmips16 lsinhelper main]]
536 pass_if_eq "$func" lsinhelper \
537     "stepping from \"lsinmips16\" back to \"lsinhelper\" ($id)"
539 # 40
540 incr id
541 set func [step_through $id [list lsinhelper main]]
542 pass_if_eq "$func" main "stepping from \"lsinhelper\" back to \"main\" ($id)"