4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003-2004 Linus Torvalds
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * Print out results of parsing for debugging and testing.
41 #include "expression.h"
44 static int show_symbol_expr(struct symbol
*sym
);
45 static int show_string_expr(struct expression
*expr
);
47 static void do_debug_symbol(struct symbol
*sym
, int indent
)
49 static const char indent_string
[] = " ";
50 static const char *typestr
[] = {
51 [SYM_UNINITIALIZED
] = "none",
52 [SYM_PREPROCESSOR
] = "cpp.",
53 [SYM_BASETYPE
] = "base",
58 [SYM_STRUCT
] = "strt",
61 [SYM_TYPEOF
] = "tpof",
62 [SYM_TYPEOF_UNQUAL
] = "tpof_unqual",
63 [SYM_BITFIELD
] = "bitf",
65 [SYM_RESTRICT
] = "rstr",
66 [SYM_FOULED
] = "foul",
69 struct context
*context
;
74 fprintf(stderr
, "%.*s%s%3d:%lu %s%s (as: %s) %p (%s:%d:%d) %s\n",
75 indent
, indent_string
, typestr
[sym
->type
],
76 sym
->bit_size
, sym
->ctype
.alignment
,
77 modifier_string(sym
->ctype
.modifiers
), show_ident(sym
->ident
),
78 show_as(sym
->ctype
.as
),
79 sym
, stream_name(sym
->pos
.stream
), sym
->pos
.line
, sym
->pos
.pos
,
80 builtin_typename(sym
) ?: "");
82 FOR_EACH_PTR(sym
->ctype
.contexts
, context
) {
83 /* FIXME: should print context expression */
84 fprintf(stderr
, "< context%d: in=%d, out=%d\n",
85 i
, context
->in
, context
->out
);
86 fprintf(stderr
, " end context%d >\n", i
);
88 } END_FOR_EACH_PTR(context
);
89 if (sym
->type
== SYM_FN
) {
92 FOR_EACH_PTR(sym
->arguments
, arg
) {
93 fprintf(stderr
, "< arg%d:\n", i
);
94 do_debug_symbol(arg
, 0);
95 fprintf(stderr
, " end arg%d >\n", i
);
97 } END_FOR_EACH_PTR(arg
);
99 do_debug_symbol(sym
->ctype
.base_type
, indent
+2);
102 void debug_symbol(struct symbol
*sym
)
104 do_debug_symbol(sym
, 0);
108 * Symbol type printout. The type system is by far the most
109 * complicated part of C - everything else is trivial.
111 static const char *show_modifiers(unsigned long mod
, int term
)
113 static char buffer
[100];
121 static struct mod_name mod_names
[] = {
123 {MOD_EXTERN
, "extern"},
124 {MOD_REGISTER
, "register"},
125 {MOD_STATIC
, "static"},
126 {MOD_INLINE
, "inline"},
127 {MOD_CONST
, "const"},
128 {MOD_RESTRICT
, "restrict"},
129 {MOD_VOLATILE
, "volatile"},
130 {MOD_ADDRESSABLE
, "[addressable]"},
131 {MOD_ASSIGNED
, "[assigned]"},
132 {MOD_ATOMIC
, "[atomic]"},
133 {MOD_BITWISE
, "[bitwise]"},
134 {MOD_EXPLICITLY_SIGNED
, "[explicitly-signed]"},
135 {MOD_GNU_INLINE
, "[gnu_inline]"},
136 {MOD_NOCAST
, "[nocast]"},
137 {MOD_NODEREF
, "[noderef]"},
138 {MOD_NORETURN
, "[noreturn]"},
139 {MOD_PURE
, "[pure]"},
140 {MOD_SAFE
, "[safe]"},
141 {MOD_SIGNED
, "[signed]"},
143 {MOD_TOPLEVEL
, "[toplevel]"},
144 {MOD_UNSIGNED
, "[unsigned]"},
145 {MOD_UNUSED
, "[unused]"},
146 {MOD_USERTYPE
, "[usertype]"},
149 for (i
= 0; i
< ARRAY_SIZE(mod_names
); i
++) {
153 const char *name
= m
->name
;
154 while ((c
= *name
++) != '\0' && len
+ 2 < sizeof buffer
)
159 if (len
&& !term
) // strip the trailing space
166 // show the modifiers, terminated by a space if not empty
167 const char *modifier_string(unsigned long mod
)
169 return show_modifiers(mod
, 1);
173 // show the modifiers, without an ending space
174 const char *modifier_name(unsigned long mod
)
176 return show_modifiers(mod
, 0);
179 static void show_struct_member(struct symbol
*sym
)
181 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym
->ident
), sym
->bit_size
, sym
->ctype
.alignment
, sym
->offset
, sym
->bit_offset
);
185 void show_symbol_list(struct symbol_list
*list
)
188 const char *prepend
= "";
190 FOR_EACH_PTR(list
, sym
) {
194 } END_FOR_EACH_PTR(sym
);
197 const char *show_as(struct ident
*as
)
201 return show_ident(as
);
209 static void FORMAT_ATTR(2) prepend(struct type_name
*name
, const char *fmt
, ...)
211 static char buffer
[512];
216 n
= vsprintf(buffer
, fmt
, args
);
220 memcpy(name
->start
, buffer
, n
);
223 static void FORMAT_ATTR(2) append(struct type_name
*name
, const char *fmt
, ...)
225 static char buffer
[512];
230 n
= vsprintf(buffer
, fmt
, args
);
233 memcpy(name
->end
, buffer
, n
);
237 static struct ctype_name
{
242 { & char_ctype
, "char", "" },
243 { &schar_ctype
, "signed char", "" },
244 { &uchar_ctype
, "unsigned char", "" },
245 { & short_ctype
, "short", "" },
246 { &sshort_ctype
, "signed short", "" },
247 { &ushort_ctype
, "unsigned short", "" },
248 { & int_ctype
, "int", "" },
249 { &sint_ctype
, "signed int", "" },
250 { &uint_ctype
, "unsigned int", "U" },
251 { & long_ctype
, "long", "L" },
252 { &slong_ctype
, "signed long", "L" },
253 { &ulong_ctype
, "unsigned long", "UL" },
254 { & llong_ctype
, "long long", "LL" },
255 { &sllong_ctype
, "signed long long", "LL" },
256 { &ullong_ctype
, "unsigned long long", "ULL" },
257 { & int128_ctype
, "__int128", "" },
258 { &sint128_ctype
, "signed __int128", "" },
259 { &uint128_ctype
, "unsigned __int128", "" },
261 { &void_ctype
, "void", "" },
262 { &bool_ctype
, "bool", "" },
264 { &float_ctype
, "float", "F" },
265 { &double_ctype
, "double", "" },
266 { &ldouble_ctype
,"long double", "L" },
267 { &incomplete_ctype
, "incomplete type", "" },
268 { &int_type
, "abstract int", "" },
269 { &fp_type
, "abstract fp", "" },
270 { &label_ctype
, "label type", "" },
271 { &bad_ctype
, "bad type", "" },
274 const char *builtin_typename(struct symbol
*sym
)
278 for (i
= 0; i
< ARRAY_SIZE(typenames
); i
++)
279 if (typenames
[i
].sym
== sym
)
280 return typenames
[i
].name
;
284 const char *builtin_type_suffix(struct symbol
*sym
)
288 for (i
= 0; i
< ARRAY_SIZE(typenames
); i
++)
289 if (typenames
[i
].sym
== sym
)
290 return typenames
[i
].suffix
;
294 const char *builtin_ctypename(struct ctype
*ctype
)
298 for (i
= 0; i
< ARRAY_SIZE(typenames
); i
++)
299 if (&typenames
[i
].sym
->ctype
== ctype
)
300 return typenames
[i
].name
;
304 static void do_show_type(struct symbol
*sym
, struct type_name
*name
)
306 const char *typename
;
307 unsigned long mod
= 0;
308 struct ident
*as
= NULL
;
314 if (sym
&& (sym
->type
!= SYM_NODE
&& sym
->type
!= SYM_ARRAY
&&
315 sym
->type
!= SYM_BITFIELD
)) {
320 prepend(name
, "%s ", show_as(as
));
322 if (sym
&& (sym
->type
== SYM_BASETYPE
|| sym
->type
== SYM_ENUM
))
323 mod
&= ~MOD_SPECIFIER
;
324 s
= modifier_string(mod
);
327 memcpy(name
->start
, s
, len
);
335 if ((typename
= builtin_typename(sym
))) {
336 int len
= strlen(typename
);
337 if (name
->start
!= name
->end
)
338 *--name
->start
= ' ';
340 memcpy(name
->start
, typename
, len
);
348 mod
= sym
->ctype
.modifiers
;
351 examine_pointer_target(sym
);
360 append(name
, "( ... )");
364 if (name
->start
!= name
->end
)
365 *--name
->start
= ' ';
366 prepend(name
, "struct %s", show_ident(sym
->ident
));
370 if (name
->start
!= name
->end
)
371 *--name
->start
= ' ';
372 prepend(name
, "union %s", show_ident(sym
->ident
));
376 prepend(name
, "enum %s ", show_ident(sym
->ident
));
381 append(name
, "%s", show_ident(sym
->ident
));
382 mod
|= sym
->ctype
.modifiers
;
383 combine_address_space(sym
->pos
, &as
, sym
->ctype
.as
);
387 mod
|= sym
->ctype
.modifiers
;
388 combine_address_space(sym
->pos
, &as
, sym
->ctype
.as
);
389 append(name
, ":%d", sym
->bit_size
);
393 append(name
, "label(%s:%p)", show_ident(sym
->ident
), sym
);
397 mod
|= sym
->ctype
.modifiers
;
398 combine_address_space(sym
->pos
, &as
, sym
->ctype
.as
);
404 append(name
, "[%lld]", get_expression_value(sym
->array_size
));
412 if (name
->start
!= name
->end
)
413 *--name
->start
= ' ';
414 prepend(name
, "restricted %s", show_ident(sym
->ident
));
422 if (name
->start
!= name
->end
)
423 *--name
->start
= ' ';
424 prepend(name
, "unknown type %d", sym
->type
);
428 sym
= sym
->ctype
.base_type
;
433 prepend(name
, "restricted ");
435 prepend(name
, "fouled ");
437 // strip trailing space
438 if (name
->end
> name
->start
&& name
->end
[-1] == ' ')
442 void show_type(struct symbol
*sym
)
445 struct type_name name
;
447 name
.start
= name
.end
= array
+100;
448 do_show_type(sym
, &name
);
450 printf("%s", name
.start
);
453 const char *show_typename(struct symbol
*sym
)
455 static char array
[200];
456 struct type_name name
;
458 name
.start
= name
.end
= array
+100;
459 do_show_type(sym
, &name
);
464 void show_symbol(struct symbol
*sym
)
471 if (sym
->ctype
.alignment
)
472 printf(".align %ld\n", sym
->ctype
.alignment
);
475 type
= sym
->ctype
.base_type
;
482 * Show actual implementation information
484 switch (type
->type
) {
485 struct symbol
*member
;
490 FOR_EACH_PTR(type
->symbol_list
, member
) {
491 show_struct_member(member
);
492 } END_FOR_EACH_PTR(member
);
497 struct statement
*stmt
= type
->stmt
;
501 val
= show_statement(stmt
);
503 printf("\tmov.%d\t\tretval,%d\n", stmt
->ret
->bit_size
, val
);
514 if (sym
->initializer
) {
516 show_expression(sym
->initializer
);
520 static int show_symbol_init(struct symbol
*sym
);
522 static int new_pseudo(void)
528 static int new_label(void)
530 static int label
= 0;
534 static void show_switch_statement(struct statement
*stmt
)
536 int val
= show_expression(stmt
->switch_expression
);
538 printf("\tswitch v%d\n", val
);
541 * Debugging only: Check that the case list is correct
542 * by printing it out.
544 * This is where a _real_ back-end would go through the
545 * cases to decide whether to use a lookup table or a
546 * series of comparisons etc
548 printf("# case table:\n");
549 FOR_EACH_PTR(stmt
->switch_case
->symbol_list
, sym
) {
550 struct statement
*case_stmt
= sym
->stmt
;
551 struct expression
*expr
= case_stmt
->case_expression
;
552 struct expression
*to
= case_stmt
->case_to
;
557 if (expr
->type
== EXPR_VALUE
) {
558 printf(" case %lld", expr
->value
);
560 if (to
->type
== EXPR_VALUE
) {
561 printf(" .. %lld", to
->value
);
569 printf(": .L%p\n", sym
);
570 } END_FOR_EACH_PTR(sym
);
571 printf("# end case table\n");
573 show_statement(stmt
->switch_statement
);
575 if (stmt
->switch_break
->used
)
576 printf(".L%p:\n", stmt
->switch_break
);
579 static void show_symbol_decl(struct symbol_list
*syms
)
582 FOR_EACH_PTR(syms
, sym
) {
583 show_symbol_init(sym
);
584 } END_FOR_EACH_PTR(sym
);
587 static int show_return_stmt(struct statement
*stmt
);
590 * Print out a statement
592 int show_statement(struct statement
*stmt
)
596 switch (stmt
->type
) {
597 case STMT_DECLARATION
:
598 show_symbol_decl(stmt
->declaration
);
601 return show_return_stmt(stmt
);
602 case STMT_COMPOUND
: {
606 if (stmt
->inline_fn
) {
607 show_statement(stmt
->args
);
608 printf("\tbegin_inline \t%s\n", show_ident(stmt
->inline_fn
->ident
));
610 FOR_EACH_PTR(stmt
->stmts
, s
) {
611 last
= show_statement(s
);
612 } END_FOR_EACH_PTR(s
);
615 printf(".L%p:\n", stmt
->ret
);
616 addr
= show_symbol_expr(stmt
->ret
);
617 bits
= stmt
->ret
->bit_size
;
619 printf("\tld.%d\t\tv%d,[v%d]\n", bits
, last
, addr
);
622 printf("\tend_inlined\t%s\n", show_ident(stmt
->inline_fn
->ident
));
626 case STMT_EXPRESSION
:
627 return show_expression(stmt
->expression
);
630 struct expression
*cond
= stmt
->if_conditional
;
632 /* This is only valid if nobody can jump into the "dead" statement */
634 if (cond
->type
== EXPR_VALUE
) {
635 struct statement
*s
= stmt
->if_true
;
642 val
= show_expression(cond
);
643 target
= new_label();
644 printf("\tje\t\tv%d,.L%d\n", val
, target
);
645 show_statement(stmt
->if_true
);
646 if (stmt
->if_false
) {
647 int last
= new_label();
648 printf("\tjmp\t\t.L%d\n", last
);
649 printf(".L%d:\n", target
);
651 show_statement(stmt
->if_false
);
653 printf(".L%d:\n", target
);
657 show_switch_statement(stmt
);
661 printf(".L%p:\n", stmt
->case_label
);
662 show_statement(stmt
->case_statement
);
665 case STMT_ITERATOR
: {
666 struct statement
*pre_statement
= stmt
->iterator_pre_statement
;
667 struct expression
*pre_condition
= stmt
->iterator_pre_condition
;
668 struct statement
*statement
= stmt
->iterator_statement
;
669 struct statement
*post_statement
= stmt
->iterator_post_statement
;
670 struct expression
*post_condition
= stmt
->iterator_post_condition
;
671 int val
, loop_top
= 0, loop_bottom
= 0;
673 show_symbol_decl(stmt
->iterator_syms
);
674 show_statement(pre_statement
);
676 if (pre_condition
->type
== EXPR_VALUE
) {
677 if (!pre_condition
->value
) {
678 loop_bottom
= new_label();
679 printf("\tjmp\t\t.L%d\n", loop_bottom
);
682 loop_bottom
= new_label();
683 val
= show_expression(pre_condition
);
684 printf("\tje\t\tv%d, .L%d\n", val
, loop_bottom
);
687 if (!post_condition
|| post_condition
->type
!= EXPR_VALUE
|| post_condition
->value
) {
688 loop_top
= new_label();
689 printf(".L%d:\n", loop_top
);
691 show_statement(statement
);
692 if (stmt
->iterator_continue
->used
)
693 printf(".L%p:\n", stmt
->iterator_continue
);
694 show_statement(post_statement
);
695 if (!post_condition
) {
696 printf("\tjmp\t\t.L%d\n", loop_top
);
697 } else if (post_condition
->type
== EXPR_VALUE
) {
698 if (post_condition
->value
)
699 printf("\tjmp\t\t.L%d\n", loop_top
);
701 val
= show_expression(post_condition
);
702 printf("\tjne\t\tv%d, .L%d\n", val
, loop_top
);
704 if (stmt
->iterator_break
->used
)
705 printf(".L%p:\n", stmt
->iterator_break
);
707 printf(".L%d:\n", loop_bottom
);
714 printf(".L%p:\n", stmt
->label_identifier
);
715 show_statement(stmt
->label_statement
);
719 if (stmt
->goto_expression
) {
720 int val
= show_expression(stmt
->goto_expression
);
721 printf("\tgoto\t\t*v%d\n", val
);
723 printf("\tgoto\t\t.L%p\n", stmt
->goto_label
);
727 printf("\tasm( .... )\n");
730 int val
= show_expression(stmt
->expression
);
731 printf("\tcontext( %d )\n", val
);
735 int val
= show_expression(stmt
->range_expression
);
736 int low
= show_expression(stmt
->range_low
);
737 int high
= show_expression(stmt
->range_high
);
738 printf("\trange( %d %d-%d)\n", val
, low
, high
);
745 static int show_call_expression(struct expression
*expr
)
747 struct symbol
*direct
;
748 struct expression
*arg
, *fn
;
753 warning(expr
->pos
, "\tcall with no type!");
758 FOR_EACH_PTR_REVERSE(expr
->args
, arg
) {
759 int new = show_expression(arg
);
760 int size
= arg
->ctype
->bit_size
;
761 printf("\tpush.%d\t\tv%d\n", size
, new);
762 framesize
+= bits_to_bytes(size
);
763 } END_FOR_EACH_PTR_REVERSE(arg
);
767 /* Remove dereference, if any */
769 if (fn
->type
== EXPR_PREOP
) {
770 if (fn
->unop
->type
== EXPR_SYMBOL
) {
771 struct symbol
*sym
= fn
->unop
->symbol
;
772 if (sym
->ctype
.base_type
->type
== SYM_FN
)
777 printf("\tcall\t\t%s\n", show_ident(direct
->ident
));
779 fncall
= show_expression(fn
);
780 printf("\tcall\t\t*v%d\n", fncall
);
783 printf("\tadd.%d\t\tvSP,vSP,$%d\n", bits_in_pointer
, framesize
);
785 retval
= new_pseudo();
786 printf("\tmov.%d\t\tv%d,retval\n", expr
->ctype
->bit_size
, retval
);
790 static int show_comma(struct expression
*expr
)
792 show_expression(expr
->left
);
793 return show_expression(expr
->right
);
796 static int show_binop(struct expression
*expr
)
798 int left
= show_expression(expr
->left
);
799 int right
= show_expression(expr
->right
);
800 int new = new_pseudo();
802 static const char *name
[] = {
803 ['+'] = "add", ['-'] = "sub",
804 ['*'] = "mul", ['/'] = "div",
805 ['%'] = "mod", ['&'] = "and",
806 ['|'] = "lor", ['^'] = "xor"
808 unsigned int op
= expr
->op
;
810 opname
= show_special(op
);
811 if (op
< ARRAY_SIZE(name
))
813 printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname
,
814 expr
->ctype
->bit_size
,
819 static int show_slice(struct expression
*expr
)
821 int target
= show_expression(expr
->base
);
822 int new = new_pseudo();
823 printf("\tslice.%d\t\tv%d,v%d,%d\n", expr
->ctype
->bit_size
, target
, new, expr
->r_bitpos
);
827 static int show_regular_preop(struct expression
*expr
)
829 int target
= show_expression(expr
->unop
);
830 int new = new_pseudo();
831 static const char *name
[] = {
832 ['!'] = "nonzero", ['-'] = "neg",
835 unsigned int op
= expr
->op
;
838 opname
= show_special(op
);
839 if (op
< ARRAY_SIZE(name
))
841 printf("\t%s.%d\t\tv%d,v%d\n", opname
, expr
->ctype
->bit_size
, new, target
);
846 * FIXME! Not all accesses are memory loads. We should
847 * check what kind of symbol is behind the dereference.
849 static int show_address_gen(struct expression
*expr
)
851 return show_expression(expr
->unop
);
854 static int show_load_gen(int bits
, struct expression
*expr
, int addr
)
856 int new = new_pseudo();
858 printf("\tld.%d\t\tv%d,[v%d]\n", bits
, new, addr
);
862 static void show_store_gen(int bits
, int value
, struct expression
*expr
, int addr
)
864 /* FIXME!!! Bitfield store! */
865 printf("\tst.%d\t\tv%d,[v%d]\n", bits
, value
, addr
);
868 static int show_assignment(struct expression
*expr
)
870 struct expression
*target
= expr
->left
;
876 bits
= expr
->ctype
->bit_size
;
877 val
= show_expression(expr
->right
);
878 addr
= show_address_gen(target
);
879 show_store_gen(bits
, val
, target
, addr
);
883 static int show_return_stmt(struct statement
*stmt
)
885 struct expression
*expr
= stmt
->ret_value
;
886 struct symbol
*target
= stmt
->ret_target
;
888 if (expr
&& expr
->ctype
) {
889 int val
= show_expression(expr
);
890 int bits
= expr
->ctype
->bit_size
;
891 int addr
= show_symbol_expr(target
);
892 show_store_gen(bits
, val
, NULL
, addr
);
894 printf("\tret\t\t(%p)\n", target
);
898 static int show_initialization(struct symbol
*sym
, struct expression
*expr
)
905 bits
= expr
->ctype
->bit_size
;
906 val
= show_expression(expr
);
907 addr
= show_symbol_expr(sym
);
908 // FIXME! The "target" expression is for bitfield store information.
909 // Leave it NULL, which works fine.
910 show_store_gen(bits
, val
, NULL
, addr
);
914 static int show_access(struct expression
*expr
)
916 int addr
= show_address_gen(expr
);
917 return show_load_gen(expr
->ctype
->bit_size
, expr
, addr
);
920 static int show_inc_dec(struct expression
*expr
, int postop
)
922 int addr
= show_address_gen(expr
->unop
);
924 const char *opname
= expr
->op
== SPECIAL_INCREMENT
? "add" : "sub";
925 int bits
= expr
->ctype
->bit_size
;
927 retval
= show_load_gen(bits
, expr
->unop
, addr
);
931 printf("\t%s.%d\t\tv%d,v%d,$1\n", opname
, bits
, new, retval
);
932 show_store_gen(bits
, new, expr
->unop
, addr
);
936 static int show_preop(struct expression
*expr
)
939 * '*' is an lvalue access, and is fundamentally different
940 * from an arithmetic operation. Maybe it should have an
941 * expression type of its own..
944 return show_access(expr
);
945 if (expr
->op
== SPECIAL_INCREMENT
|| expr
->op
== SPECIAL_DECREMENT
)
946 return show_inc_dec(expr
, 0);
947 return show_regular_preop(expr
);
950 static int show_postop(struct expression
*expr
)
952 return show_inc_dec(expr
, 1);
955 static int show_symbol_expr(struct symbol
*sym
)
957 int new = new_pseudo();
959 if (sym
->initializer
&& sym
->initializer
->type
== EXPR_STRING
)
960 return show_string_expr(sym
->initializer
);
962 if (sym
->ctype
.modifiers
& (MOD_TOPLEVEL
| MOD_EXTERN
| MOD_STATIC
)) {
963 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer
, new, show_ident(sym
->ident
));
966 if (sym
->ctype
.modifiers
& MOD_ADDRESSABLE
) {
967 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer
, new, 0LL);
970 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer
, new, show_ident(sym
->ident
), sym
);
974 static int show_symbol_init(struct symbol
*sym
)
976 struct expression
*expr
= sym
->initializer
;
981 bits
= expr
->ctype
->bit_size
;
982 val
= show_expression(expr
);
983 addr
= show_symbol_expr(sym
);
984 show_store_gen(bits
, val
, NULL
, addr
);
989 static int show_cast_expr(struct expression
*expr
)
991 struct symbol
*old_type
, *new_type
;
992 int op
= show_expression(expr
->cast_expression
);
993 int oldbits
, newbits
;
996 old_type
= expr
->cast_expression
->ctype
;
997 new_type
= expr
->cast_type
;
999 oldbits
= old_type
->bit_size
;
1000 newbits
= new_type
->bit_size
;
1001 if (oldbits
>= newbits
)
1004 is_signed
= is_signed_type(old_type
);
1006 printf("\tsext%d.%d\tv%d,v%d\n", oldbits
, newbits
, new, op
);
1008 printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits
, new, op
, (1UL << oldbits
)-1);
1013 static int show_value(struct expression
*expr
)
1015 int new = new_pseudo();
1016 unsigned long long value
= expr
->value
;
1018 printf("\tmovi.%d\t\tv%d,$%llu\n", expr
->ctype
->bit_size
, new, value
);
1022 static int show_fvalue(struct expression
*expr
)
1024 int new = new_pseudo();
1025 long double value
= expr
->fvalue
;
1027 printf("\tmovf.%d\t\tv%d,$%Le\n", expr
->ctype
->bit_size
, new, value
);
1031 static int show_string_expr(struct expression
*expr
)
1033 int new = new_pseudo();
1035 printf("\tmovi.%d\t\tv%d,&%s\n", bits_in_pointer
, new, show_string(expr
->string
));
1039 static int show_label_expr(struct expression
*expr
)
1041 int new = new_pseudo();
1042 printf("\tmovi.%d\t\tv%d,.L%p\n",bits_in_pointer
, new, expr
->label_symbol
);
1046 static int show_conditional_expr(struct expression
*expr
)
1048 int cond
= show_expression(expr
->conditional
);
1049 int valt
= show_expression(expr
->cond_true
);
1050 int valf
= show_expression(expr
->cond_false
);
1051 int new = new_pseudo();
1053 printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond
, expr
->ctype
->bit_size
, new, valt
, valf
);
1057 static int show_statement_expr(struct expression
*expr
)
1059 return show_statement(expr
->statement
);
1062 static int show_position_expr(struct expression
*expr
, struct symbol
*base
)
1064 int new = show_expression(expr
->init_expr
);
1065 struct symbol
*ctype
= expr
->init_expr
->ctype
;
1068 bit_offset
= ctype
? ctype
->bit_offset
: -1;
1070 printf("\tinsert v%d at [%d:%d] of %s\n", new,
1071 expr
->init_offset
, bit_offset
,
1072 show_ident(base
->ident
));
1076 static int show_initializer_expr(struct expression
*expr
, struct symbol
*ctype
)
1078 struct expression
*entry
;
1080 FOR_EACH_PTR(expr
->expr_list
, entry
) {
1083 // Nested initializers have their positions already
1084 // recursively calculated - just output them too
1085 if (entry
->type
== EXPR_INITIALIZER
) {
1086 show_initializer_expr(entry
, ctype
);
1090 // Initializer indexes and identifiers should
1091 // have been evaluated to EXPR_POS
1092 if (entry
->type
== EXPR_IDENTIFIER
) {
1093 printf(" AT '%s':\n", show_ident(entry
->expr_ident
));
1094 entry
= entry
->ident_expression
;
1098 if (entry
->type
== EXPR_INDEX
) {
1099 printf(" AT '%d..%d:\n", entry
->idx_from
, entry
->idx_to
);
1100 entry
= entry
->idx_expression
;
1103 if (entry
->type
== EXPR_POS
) {
1104 show_position_expr(entry
, ctype
);
1107 show_initialization(ctype
, entry
);
1108 } END_FOR_EACH_PTR(entry
);
1112 int show_symbol_expr_init(struct symbol
*sym
)
1114 struct expression
*expr
= sym
->initializer
;
1117 show_expression(expr
);
1118 return show_symbol_expr(sym
);
1122 * Print out an expression. Return the pseudo that contains the
1125 int show_expression(struct expression
*expr
)
1131 struct position
*pos
= &expr
->pos
;
1132 printf("\tno type at %s:%d:%d\n",
1133 stream_name(pos
->stream
),
1134 pos
->line
, pos
->pos
);
1138 switch (expr
->type
) {
1140 return show_call_expression(expr
);
1142 case EXPR_ASSIGNMENT
:
1143 return show_assignment(expr
);
1146 return show_comma(expr
);
1150 return show_binop(expr
);
1152 return show_preop(expr
);
1154 return show_postop(expr
);
1156 return show_symbol_expr(expr
->symbol
);
1159 case EXPR_PTRSIZEOF
:
1162 warning(expr
->pos
, "invalid expression after evaluation");
1165 case EXPR_FORCE_CAST
:
1166 case EXPR_IMPLIED_CAST
:
1167 return show_cast_expr(expr
);
1169 return show_value(expr
);
1171 return show_fvalue(expr
);
1173 return show_string_expr(expr
);
1174 case EXPR_INITIALIZER
:
1175 return show_initializer_expr(expr
, expr
->ctype
);
1177 case EXPR_CONDITIONAL
:
1178 return show_conditional_expr(expr
);
1179 case EXPR_STATEMENT
:
1180 return show_statement_expr(expr
);
1182 return show_label_expr(expr
);
1184 return show_slice(expr
);
1186 // None of these should exist as direct expressions: they are only
1187 // valid as sub-expressions of initializers.
1189 warning(expr
->pos
, "unable to show plain initializer position expression");
1191 case EXPR_IDENTIFIER
:
1192 warning(expr
->pos
, "unable to show identifier expression");
1195 warning(expr
->pos
, "unable to show index expression");
1198 warning(expr
->pos
, "unable to show type expression");
1201 warning(expr
->pos
, "unable to show generic expression");