Saves some lines of code.
Unified · Split
| @@ -4142,7 +4142,7 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td) · 4141 unmodified lines | ||
| 4142 | 4142 | mk_pointer(type); |
| 4143 | 4143 | type->t |= qualifiers; |
| 4144 | 4144 | } |
| 4145 | − | |
| 4145 | + | |
| 4146 | 4146 | /* recursive type */ |
| 4147 | 4147 | /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */ |
| 4148 | 4148 | type1.t = 0; /* XXX: same as int */ |
| @@ -4290,6 +4290,27 @@ static void vpush_tokc(int t) · 141 unmodified lines | ||
| 4290 | 4290 | vsetc(&type, VT_CONST, &tokc); |
| 4291 | 4291 | } |
| 4292 | 4292 | |
| 4293 | +static void parse_builtin_params(int nc, const char *args) | |
| 4294 | +{ | |
| 4295 | + char c, sep = '('; | |
| 4296 | + CType t; | |
| 4297 | + if (nc) | |
| 4298 | + nocode_wanted++; | |
| 4299 | + next(); | |
| 4300 | + while ((c = *args++)) { | |
| 4301 | + skip(sep); | |
| 4302 | + sep = ','; | |
| 4303 | + switch (c) { | |
| 4304 | + case 'e': expr_eq(); continue; | |
| 4305 | + case 't': parse_type(&t); vpush(&t); continue; | |
| 4306 | + default: tcc_error("internal error"); break; | |
| 4307 | + } | |
| 4308 | + } | |
| 4309 | + skip(')'); | |
| 4310 | + if (nc) | |
| 4311 | + nocode_wanted--; | |
| 4312 | +} | |
| 4313 | + | |
| 4293 | 4314 | ST_FUNC void unary(void) |
| 4294 | 4315 | { |
| 4295 | 4316 | int n, t, align, size, r, sizeof_caller; |
| @@ -4497,30 +4518,17 @@ ST_FUNC void unary(void) · 201 unmodified lines | ||
| 4497 | 4518 | break; |
| 4498 | 4519 | |
| 4499 | 4520 | case TOK_builtin_expect: |
| 4500 | − { | |
| 4501 | − /* __builtin_expect is a no-op for now */ | |
| 4502 | − next(); | |
| 4503 | − skip('('); | |
| 4504 | − expr_eq(); | |
| 4505 | − skip(','); | |
| 4506 | − expr_eq(); | |
| 4507 | − vpop(); | |
| 4508 | − skip(')'); | |
| 4509 | − } | |
| 4521 | + /* __builtin_expect is a no-op for now */ | |
| 4522 | + parse_builtin_params(0, "ee"); | |
| 4523 | + vpop(); | |
| 4510 | 4524 | break; |
| 4511 | 4525 | case TOK_builtin_types_compatible_p: |
| 4512 | − { | |
| 4513 | − CType type1, type2; | |
| 4514 | − next(); | |
| 4515 | − skip('('); | |
| 4516 | − parse_type(&type1); | |
| 4517 | − skip(','); | |
| 4518 | − parse_type(&type2); | |
| 4519 | − skip(')'); | |
| 4520 | − type1.t &= ~(VT_CONSTANT | VT_VOLATILE); | |
| 4521 | − type2.t &= ~(VT_CONSTANT | VT_VOLATILE); | |
| 4522 | − vpushi(is_compatible_types(&type1, &type2)); | |
| 4523 | − } | |
| 4526 | + parse_builtin_params(0, "tt"); | |
| 4527 | + vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE); | |
| 4528 | + vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE); | |
| 4529 | + n = is_compatible_types(&vtop[-1].type, &vtop[0].type); | |
| 4530 | + vtop -= 2; | |
| 4531 | + vpushi(n); | |
| 4524 | 4532 | break; |
| 4525 | 4533 | case TOK_builtin_choose_expr: |
| 4526 | 4534 | { |
| @@ -4550,18 +4558,10 @@ ST_FUNC void unary(void) · 23 unmodified lines | ||
| 4550 | 4558 | } |
| 4551 | 4559 | break; |
| 4552 | 4560 | case TOK_builtin_constant_p: |
| 4553 | − { | |
| 4554 | − int res; | |
| 4555 | − next(); | |
| 4556 | − skip('('); | |
| 4557 | − nocode_wanted++; | |
| 4558 | − expr_eq(); | |
| 4559 | − res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; | |
| 4560 | − vpop(); | |
| 4561 | − nocode_wanted--; | |
| 4562 | − skip(')'); | |
| 4563 | − vpushi(res); | |
| 4564 | − } | |
| 4561 | + parse_builtin_params(1, "e"); | |
| 4562 | + n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; | |
| 4563 | + vtop--; | |
| 4564 | + vpushi(n); | |
| 4565 | 4565 | break; |
| 4566 | 4566 | case TOK_builtin_frame_address: |
| 4567 | 4567 | case TOK_builtin_return_address: |
| @@ -4599,43 +4599,27 @@ ST_FUNC void unary(void) · 31 unmodified lines | ||
| 4599 | 4599 | #ifdef TCC_TARGET_X86_64 |
| 4600 | 4600 | #ifdef TCC_TARGET_PE |
| 4601 | 4601 | case TOK_builtin_va_start: |
| 4602 | − { | |
| 4603 | − next(); | |
| 4604 | − skip('('); | |
| 4605 | − expr_eq(); | |
| 4606 | − skip(','); | |
| 4607 | − expr_eq(); | |
| 4608 | − skip(')'); | |
| 4609 | − if ((vtop->r & VT_VALMASK) != VT_LOCAL) | |
| 4610 | − tcc_error("__builtin_va_start expects a local variable"); | |
| 4611 | − vtop->r &= ~VT_LVAL; | |
| 4612 | − vtop->type = char_pointer_type; | |
| 4613 | − vtop->c.i += 8; | |
| 4614 | − vstore(); | |
| 4615 | − } | |
| 4602 | + parse_builtin_params(0, "ee"); | |
| 4603 | + if ((vtop->r & VT_VALMASK) != VT_LOCAL) | |
| 4604 | + tcc_error("__builtin_va_start expects a local variable"); | |
| 4605 | + vtop->r &= ~VT_LVAL; | |
| 4606 | + vtop->type = char_pointer_type; | |
| 4607 | + vtop->c.i += 8; | |
| 4608 | + vstore(); | |
| 4616 | 4609 | break; |
| 4617 | 4610 | #else |
| 4618 | 4611 | case TOK_builtin_va_arg_types: |
| 4619 | − { | |
| 4620 | − CType type; | |
| 4621 | − next(); | |
| 4622 | − skip('('); | |
| 4623 | − parse_type(&type); | |
| 4624 | − skip(')'); | |
| 4625 | − vpushi(classify_x86_64_va_arg(&type)); | |
| 4626 | − } | |
| 4612 | + parse_builtin_params(0, "t"); | |
| 4613 | + vpushi(classify_x86_64_va_arg(&vtop->type)); | |
| 4614 | + vswap(); | |
| 4615 | + vpop(); | |
| 4627 | 4616 | break; |
| 4628 | 4617 | #endif |
| 4629 | 4618 | #endif |
| 4630 | 4619 | |
| 4631 | 4620 | #ifdef TCC_TARGET_ARM64 |
| 4632 | 4621 | case TOK___va_start: { |
| 4633 | − next(); | |
| 4634 | − skip('('); | |
| 4635 | − expr_eq(); | |
| 4636 | − skip(','); | |
| 4637 | − expr_eq(); | |
| 4638 | − skip(')'); | |
| 4622 | + parse_builtin_params(0, "ee"); | |
| 4639 | 4623 | //xx check types |
| 4640 | 4624 | gen_va_start(); |
| 4641 | 4625 | vpushi(0); |
| @@ -4644,24 +4628,16 @@ ST_FUNC void unary(void) · 2 unmodified lines | ||
| 4644 | 4628 | } |
| 4645 | 4629 | case TOK___va_arg: { |
| 4646 | 4630 | CType type; |
| 4647 | − next(); | |
| 4648 | − skip('('); | |
| 4649 | − expr_eq(); | |
| 4650 | − skip(','); | |
| 4651 | − parse_type(&type); | |
| 4652 | − skip(')'); | |
| 4631 | + parse_builtin_params(0, "et"); | |
| 4632 | + type = vtop->type; | |
| 4633 | + vpop(); | |
| 4653 | 4634 | //xx check types |
| 4654 | 4635 | gen_va_arg(&type); |
| 4655 | 4636 | vtop->type = type; |
| 4656 | 4637 | break; |
| 4657 | 4638 | } |
| 4658 | 4639 | case TOK___arm64_clear_cache: { |
| 4659 | − next(); | |
| 4660 | − skip('('); | |
| 4661 | − expr_eq(); | |
| 4662 | − skip(','); | |
| 4663 | − expr_eq(); | |
| 4664 | − skip(')'); | |
| 4640 | + parse_builtin_params(0, "ee"); | |
| 4665 | 4641 | gen_clear_cache(); |
| 4666 | 4642 | vpushi(0); |
| 4667 | 4643 | vtop->type.t = VT_VOID; |
| @@ -4717,7 +4693,7 @@ ST_FUNC void unary(void) · 49 unmodified lines | ||
| 4717 | 4693 | vpushsym(&s->type, s); |
| 4718 | 4694 | next(); |
| 4719 | 4695 | break; |
| 4720 | − | |
| 4696 | + | |
| 4721 | 4697 | // special qnan , snan and infinity values |
| 4722 | 4698 | case TOK___NAN__: |
| 4723 | 4699 | vpush64(VT_DOUBLE, 0x7ff8000000000000ULL); |