Revert "Fix wrong handling of strings..." (almost)
See commite588b65390. Was not "wrong" really, just different. But appears to be outdated. Now disabled by default (top of tccpp.c: ACCEPT_LF_IN_STRINGS) Also, in skipped code, just warn. Also: cleanup "Optimize small structure copying on x86_64" (commit3715f1d7ee) - remove some copy&paste coding (tccgen.c) - RSI/RDI need to be preserved on windows - simply don't use under bcheck (this is tinycc)
This commit is contained in:
		
							parent
							
								
									e588b65390
								
							
						
					
					
						commit
						af1abf1f45
					
				
					 8 changed files with 100 additions and 131 deletions
				
			
		
							
								
								
									
										13
									
								
								lib/bcheck.c
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								lib/bcheck.c
									
										
									
									
									
								
							|  | @ -294,7 +294,6 @@ DLL_EXPORT int __bound_strncmp(const char *s1, const char *s2, size_t n); | ||||||
| DLL_EXPORT char *__bound_strcat(char *dest, const char *src); | DLL_EXPORT char *__bound_strcat(char *dest, const char *src); | ||||||
| DLL_EXPORT char *__bound_strchr(const char *string, int ch); | DLL_EXPORT char *__bound_strchr(const char *string, int ch); | ||||||
| DLL_EXPORT char *__bound_strdup(const char *s); | DLL_EXPORT char *__bound_strdup(const char *s); | ||||||
| DLL_EXPORT void __bound_struct_copy(void *dst,void *src,size_t size); |  | ||||||
| 
 | 
 | ||||||
| #if defined(__arm__) && defined(__ARM_EABI__) | #if defined(__arm__) && defined(__ARM_EABI__) | ||||||
| DLL_EXPORT void *__bound___aeabi_memcpy(void *dst, const void *src, size_t size); | DLL_EXPORT void *__bound___aeabi_memcpy(void *dst, const void *src, size_t size); | ||||||
|  | @ -427,7 +426,6 @@ static unsigned long long bound_strncmp_count; | ||||||
| static unsigned long long bound_strcat_count; | static unsigned long long bound_strcat_count; | ||||||
| static unsigned long long bound_strchr_count; | static unsigned long long bound_strchr_count; | ||||||
| static unsigned long long bound_strdup_count; | static unsigned long long bound_strdup_count; | ||||||
| static unsigned long long bound_struct_copy_count; |  | ||||||
| static unsigned long long bound_not_found; | static unsigned long long bound_not_found; | ||||||
| #define INCR_COUNT(x)          ++x | #define INCR_COUNT(x)          ++x | ||||||
| #else | #else | ||||||
|  | @ -1262,7 +1260,6 @@ void __attribute__((destructor)) __bound_exit(void) | ||||||
|             fprintf (stderr, "bound_strcat_count       %llu\n", bound_strcat_count); |             fprintf (stderr, "bound_strcat_count       %llu\n", bound_strcat_count); | ||||||
|             fprintf (stderr, "bound_strchr_count       %llu\n", bound_strchr_count); |             fprintf (stderr, "bound_strchr_count       %llu\n", bound_strchr_count); | ||||||
|             fprintf (stderr, "bound_strdup_count       %llu\n", bound_strdup_count); |             fprintf (stderr, "bound_strdup_count       %llu\n", bound_strdup_count); | ||||||
|             fprintf (stderr, "bound_struct_copy_count  %llu\n", bound_struct_copy_count); |  | ||||||
|             fprintf (stderr, "bound_not_found          %llu\n", bound_not_found); |             fprintf (stderr, "bound_not_found          %llu\n", bound_not_found); | ||||||
| #endif | #endif | ||||||
| #if BOUND_STATISTIC_SPLAY | #if BOUND_STATISTIC_SPLAY | ||||||
|  | @ -1786,16 +1783,6 @@ void *__bound_memset(void *s, int c, size_t n) | ||||||
|     return memset(s, c, n); |     return memset(s, c, n); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void __bound_struct_copy(void *dst,void *src,size_t size) |  | ||||||
| { |  | ||||||
|     dprintf(stderr, "Copy struct from %p to %p,size %lx\n", |  | ||||||
|             src,dst,size); |  | ||||||
|     INCR_COUNT(bound_struct_copy_count); |  | ||||||
|     __bound_check(dst,size,"struct copy destination"); |  | ||||||
|     __bound_check(src,size,"struct copy source"); |  | ||||||
|     return; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #if defined(__arm__) && defined(__ARM_EABI__) | #if defined(__arm__) && defined(__ARM_EABI__) | ||||||
| void *__bound___aeabi_memcpy(void *dest, const void *src, size_t n) | void *__bound___aeabi_memcpy(void *dest, const void *src, size_t n) | ||||||
| { | { | ||||||
|  |  | ||||||
							
								
								
									
										3
									
								
								tcc.h
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								tcc.h
									
										
									
									
									
								
							|  | @ -1644,8 +1644,6 @@ ST_FUNC void gen_increment_tcov (SValue *sv); | ||||||
| 
 | 
 | ||||||
| /* ------------ x86_64-gen.c ------------ */ | /* ------------ x86_64-gen.c ------------ */ | ||||||
| #ifdef TCC_TARGET_X86_64 | #ifdef TCC_TARGET_X86_64 | ||||||
| #define TCC_TARGET_NATIVE_STRUCT_COPY |  | ||||||
| ST_FUNC void gen_struct_copy(int size); |  | ||||||
| ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c); | ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c); | ||||||
| ST_FUNC void gen_opl(int op); | ST_FUNC void gen_opl(int op); | ||||||
| #ifdef TCC_TARGET_PE | #ifdef TCC_TARGET_PE | ||||||
|  | @ -1691,7 +1689,6 @@ ST_FUNC void gen_increment_tcov (SValue *sv); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /* ------------ tcccoff.c ------------ */ | /* ------------ tcccoff.c ------------ */ | ||||||
| 
 |  | ||||||
| #ifdef TCC_TARGET_COFF | #ifdef TCC_TARGET_COFF | ||||||
| ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f); | ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f); | ||||||
| ST_FUNC int tcc_load_coff(TCCState * s1, int fd); | ST_FUNC int tcc_load_coff(TCCState * s1, int fd); | ||||||
|  |  | ||||||
							
								
								
									
										84
									
								
								tccgen.c
									
										
									
									
									
								
							
							
						
						
									
										84
									
								
								tccgen.c
									
										
									
									
									
								
							|  | @ -3468,54 +3468,42 @@ ST_FUNC void vstore(void) | ||||||
|     ft = vtop[-1].type.t; |     ft = vtop[-1].type.t; | ||||||
|     sbt = vtop->type.t & VT_BTYPE; |     sbt = vtop->type.t & VT_BTYPE; | ||||||
|     dbt = ft & VT_BTYPE; |     dbt = ft & VT_BTYPE; | ||||||
| 
 |  | ||||||
|     verify_assign_cast(&vtop[-1].type); |     verify_assign_cast(&vtop[-1].type); | ||||||
| 
 | 
 | ||||||
|     if (sbt == VT_STRUCT) { |     if (sbt == VT_STRUCT) { | ||||||
|         /* if structure, only generate pointer */ |         /* if structure, only generate pointer */ | ||||||
|         /* structure assignment : generate memcpy */ |         /* structure assignment : generate memcpy */ | ||||||
|             size = type_size(&vtop->type, &align); |         size = type_size(&vtop->type, &align); | ||||||
|  |         /* destination, keep on stack() as result */ | ||||||
|  |         vpushv(vtop - 1); | ||||||
|  | #ifdef CONFIG_TCC_BCHECK | ||||||
|  |         if (vtop->r & VT_MUSTBOUND) | ||||||
|  |             gbound(); /* check would be wrong after gaddrof() */ | ||||||
|  | #endif | ||||||
|  |         vtop->type.t = VT_PTR; | ||||||
|  |         gaddrof(); | ||||||
|  |         /* source */ | ||||||
|  |         vswap(); | ||||||
|  | #ifdef CONFIG_TCC_BCHECK | ||||||
|  |         if (vtop->r & VT_MUSTBOUND) | ||||||
|  |             gbound(); | ||||||
|  | #endif | ||||||
|  |         vtop->type.t = VT_PTR; | ||||||
|  |         gaddrof(); | ||||||
| 
 | 
 | ||||||
| #ifdef TCC_TARGET_NATIVE_STRUCT_COPY | #ifdef TCC_TARGET_NATIVE_STRUCT_COPY | ||||||
|             if (size <= (PTR_SIZE << 4)) { |         if (1 | ||||||
| 		    vswap(); |  | ||||||
| #ifdef CONFIG_TCC_BCHECK | #ifdef CONFIG_TCC_BCHECK | ||||||
|                     if (vtop->r & VT_MUSTBOUND) |             && !tcc_state->do_bounds_check | ||||||
|                         gbound(); |  | ||||||
| #endif | #endif | ||||||
|                     vtop->type.t = VT_PTR; |             ) { | ||||||
|                     gaddrof(); |             gen_struct_copy(size); | ||||||
| 
 |         } else | ||||||
|                     vpushv(vtop - 1); |  | ||||||
| #ifdef CONFIG_TCC_BCHECK |  | ||||||
|                     if (vtop->r & VT_MUSTBOUND) |  | ||||||
|                         gbound(); |  | ||||||
| #endif | #endif | ||||||
|                     vtop->type.t = VT_PTR; |         { | ||||||
|                     gaddrof();                  /* src dest src */ |             /* type size */ | ||||||
| #ifdef CONFIG_TCC_BCHECK |             vpushi(size); | ||||||
|                     if (tcc_state->do_bounds_check) { |             /* Use memmove, rather than memcpy, as dest and src may be same: */ | ||||||
|                         vpush_helper_func(TOK___bound_struct_copy); |  | ||||||
|                         vpushv(vtop - 2); |  | ||||||
|                         vpushv(vtop - 2); |  | ||||||
|                         vpushi(size); |  | ||||||
|                         gfunc_call(3); |  | ||||||
|                     } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|                     gen_struct_copy(size); |  | ||||||
|             } else { |  | ||||||
| #endif |  | ||||||
|             /* destination */ |  | ||||||
|             vswap(); |  | ||||||
| #ifdef CONFIG_TCC_BCHECK |  | ||||||
|             if (vtop->r & VT_MUSTBOUND) |  | ||||||
|                 gbound(); /* check would be wrong after gaddrof() */ |  | ||||||
| #endif |  | ||||||
|             vtop->type.t = VT_PTR; |  | ||||||
|             gaddrof(); |  | ||||||
| 
 |  | ||||||
|             /* address of memcpy() */ |  | ||||||
| #ifdef TCC_ARM_EABI | #ifdef TCC_ARM_EABI | ||||||
|             if(!(align & 7)) |             if(!(align & 7)) | ||||||
|                 vpush_helper_func(TOK_memmove8); |                 vpush_helper_func(TOK_memmove8); | ||||||
|  | @ -3523,25 +3511,11 @@ ST_FUNC void vstore(void) | ||||||
|                 vpush_helper_func(TOK_memmove4); |                 vpush_helper_func(TOK_memmove4); | ||||||
|             else |             else | ||||||
| #endif | #endif | ||||||
|             /* Use memmove, rather than memcpy, as dest and src may be same: */ |  | ||||||
|             vpush_helper_func(TOK_memmove); |             vpush_helper_func(TOK_memmove); | ||||||
| 
 |             vrott(4); | ||||||
|             vswap(); |  | ||||||
|             /* source */ |  | ||||||
|             vpushv(vtop - 2); |  | ||||||
| #ifdef CONFIG_TCC_BCHECK |  | ||||||
|             if (vtop->r & VT_MUSTBOUND) |  | ||||||
|                 gbound(); |  | ||||||
| #endif |  | ||||||
|             vtop->type.t = VT_PTR; |  | ||||||
|             gaddrof(); |  | ||||||
|             /* type size */ |  | ||||||
|             vpushi(size); |  | ||||||
|             gfunc_call(3); |             gfunc_call(3); | ||||||
|         /* leave source on stack */ |         } | ||||||
| #ifdef TCC_TARGET_NATIVE_STRUCT_COPY | 
 | ||||||
|             } |  | ||||||
| #endif |  | ||||||
|     } else if (ft & VT_BITFIELD) { |     } else if (ft & VT_BITFIELD) { | ||||||
|         /* bitfield store handling */ |         /* bitfield store handling */ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								tccpp.c
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								tccpp.c
									
										
									
									
									
								
							|  | @ -21,6 +21,9 @@ | ||||||
| #define USING_GLOBALS | #define USING_GLOBALS | ||||||
| #include "tcc.h" | #include "tcc.h" | ||||||
| 
 | 
 | ||||||
|  | /* #define to 1 to enable (see parse_pp_string()) */ | ||||||
|  | #define ACCEPT_LF_IN_STRINGS 0 | ||||||
|  | 
 | ||||||
| /********************************************************/ | /********************************************************/ | ||||||
| /* global variables */ | /* global variables */ | ||||||
| 
 | 
 | ||||||
|  | @ -944,16 +947,26 @@ static uint8_t *parse_pp_string(uint8_t *p, | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } else if (c == '\n') { |         } else if (c == '\n') { | ||||||
|             tcc_error("missing terminating %c character",sep); |         add_lf: | ||||||
|  |             if (ACCEPT_LF_IN_STRINGS) { | ||||||
|  |                 file->line_num++; | ||||||
|  |                 goto add_char; | ||||||
|  |             } else if (str) { /* not skipping */ | ||||||
|  |                 goto unterminated_string; | ||||||
|  |             } else { | ||||||
|  |                 tcc_warning("missing terminating %c character", sep); | ||||||
|  |                 return p; | ||||||
|  |             } | ||||||
|         } else if (c == '\r') { |         } else if (c == '\r') { | ||||||
|             PEEKC_EOB(c, p); |             PEEKC_EOB(c, p); | ||||||
|             if (c != '\n') { |             if (c != '\n') { | ||||||
|                 if (str) |                 if (str) | ||||||
|                     cstr_ccat(str, '\r'); |                     cstr_ccat(str, '\r'); | ||||||
|             } else { |             } else { | ||||||
|                 tcc_error("missing terminating %c character",sep); |                 goto add_lf; | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|  |         add_char: | ||||||
|             if (str) |             if (str) | ||||||
|                 cstr_ccat(str, c); |                 cstr_ccat(str, c); | ||||||
|             p++; |             p++; | ||||||
|  | @ -1006,6 +1019,7 @@ redo_start: | ||||||
|         case '\'': |         case '\'': | ||||||
|             if (in_warn_or_error) |             if (in_warn_or_error) | ||||||
|                 goto _default; |                 goto _default; | ||||||
|  |             tok_flags &= ~TOK_FLAG_BOL; | ||||||
|             p = parse_pp_string(p, c, NULL); |             p = parse_pp_string(p, c, NULL); | ||||||
|             break; |             break; | ||||||
|         /* skip comments */ |         /* skip comments */ | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								tcctok.h
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								tcctok.h
									
										
									
									
									
								
							|  | @ -330,7 +330,6 @@ | ||||||
|      DEF(TOK___bound_setjmp, "__bound_setjmp") |      DEF(TOK___bound_setjmp, "__bound_setjmp") | ||||||
|      DEF(TOK___bound_longjmp, "__bound_longjmp") |      DEF(TOK___bound_longjmp, "__bound_longjmp") | ||||||
|      DEF(TOK___bound_new_region, "__bound_new_region") |      DEF(TOK___bound_new_region, "__bound_new_region") | ||||||
|      DEF(TOK___bound_struct_copy,"__bound_struct_copy") |  | ||||||
| # ifdef TCC_TARGET_PE | # ifdef TCC_TARGET_PE | ||||||
| #  ifdef TCC_TARGET_X86_64 | #  ifdef TCC_TARGET_X86_64 | ||||||
|      DEF(TOK___bound_alloca_nr, "__bound_alloca_nr") |      DEF(TOK___bound_alloca_nr, "__bound_alloca_nr") | ||||||
|  |  | ||||||
|  | @ -1519,8 +1519,6 @@ struct structa1 { | ||||||
|     char f2; |     char f2; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct structa1 ssta1; |  | ||||||
| 
 |  | ||||||
| void struct_assign_test1(struct structa1 s1, int t, float f) | void struct_assign_test1(struct structa1 s1, int t, float f) | ||||||
| { | { | ||||||
|     printf("%d %d %d %f\n", s1.f1, s1.f2, t, f); |     printf("%d %d %d %f\n", s1.f1, s1.f2, t, f); | ||||||
|  | @ -1538,22 +1536,12 @@ void struct_assign_test(void) | ||||||
|     struct S { |     struct S { | ||||||
|       struct structa1 lsta1, lsta2; |       struct structa1 lsta1, lsta2; | ||||||
|       int i; |       int i; | ||||||
|     } s, *ps; |     } s = {{1,2}, {3,4}}, *ps; | ||||||
|      |      | ||||||
|     ps = &s; |     ps = &s; | ||||||
|     ps->i = 4; |     ps->i = 4; | ||||||
| #if 0 | 
 | ||||||
|     s.lsta1.f1 = 1; |  | ||||||
|     s.lsta1.f2 = 2; |  | ||||||
|     printf("%d %d\n", s.lsta1.f1, s.lsta1.f2); |  | ||||||
|     s.lsta2 = s.lsta1; |  | ||||||
|     printf("%d %d\n", s.lsta2.f1, s.lsta2.f2); |  | ||||||
| #else |  | ||||||
|     s.lsta2.f1 = 1; |  | ||||||
|     s.lsta2.f2 = 2; |  | ||||||
| #endif |  | ||||||
|     struct_assign_test1(ps->lsta2, 3, 4.5); |     struct_assign_test1(ps->lsta2, 3, 4.5); | ||||||
|      |  | ||||||
|     printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2); |     printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2); | ||||||
|     ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i); |     ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i); | ||||||
|     printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2); |     printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2); | ||||||
|  | @ -1565,6 +1553,9 @@ void struct_assign_test(void) | ||||||
|         { struct_assign_test } |         { struct_assign_test } | ||||||
|     }; |     }; | ||||||
|     printf("%d\n", struct_assign_test == t[0].elem); |     printf("%d\n", struct_assign_test == t[0].elem); | ||||||
|  | 
 | ||||||
|  |     s.lsta1 = s.lsta2 = struct_assign_test2(s.lsta1, 1); | ||||||
|  |     printf("%d %d\n", s.lsta1.f1, s.lsta1.f2); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* casts to short/char */ | /* casts to short/char */ | ||||||
|  | @ -4253,6 +4244,12 @@ void func_arg_test(void) | ||||||
| /* gcc 2.95.3 does not handle correctly CR in strings or after strays */ | /* gcc 2.95.3 does not handle correctly CR in strings or after strays */ | ||||||
| #define CORRECT_CR_HANDLING | #define CORRECT_CR_HANDLING | ||||||
| 
 | 
 | ||||||
|  | /* deprecated and no longer supported in gcc 3.3 */ | ||||||
|  | /* no longer supported by default in TinyCC */ | ||||||
|  | #ifdef __TINYC__ | ||||||
|  | /* # define ACCEPT_LF_IN_STRINGS */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| /* keep this as the last test because GCC messes up line-numbers
 | /* keep this as the last test because GCC messes up line-numbers
 | ||||||
|    with the ^L^K^M characters below */ |    with the ^L^K^M characters below */ | ||||||
| void whitespace_test(void) | void whitespace_test(void) | ||||||
|  | @ -4274,6 +4271,20 @@ ntf("aaa=%d\n", 3); | ||||||
| \ | \ | ||||||
| ntf("min=%d\n", 4); | ntf("min=%d\n", 4); | ||||||
| 
 | 
 | ||||||
|  | #ifdef ACCEPT_LF_IN_STRINGS | ||||||
|  |     printf("len1=%d\n", strlen(" | ||||||
|  | ")); | ||||||
|  | #ifdef CORRECT_CR_HANDLING | ||||||
|  |     str = " | ||||||
|  | "; | ||||||
|  |     printf("len1=%d str[0]=%d\n", strlen(str), str[0]); | ||||||
|  | #endif | ||||||
|  |     printf("len1=%d\n", strlen("
a | ||||||
|  | ")); | ||||||
|  | #else | ||||||
|  |     printf("len1=1\nlen1=1 str[0]=10\nlen1=3\n"); | ||||||
|  | #endif /* ACCEPT_LF_IN_STRINGS */ | ||||||
|  | 
 | ||||||
| #ifdef __LINE__ | #ifdef __LINE__ | ||||||
|     printf("__LINE__ defined\n"); |     printf("__LINE__ defined\n"); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -105,8 +105,7 @@ GEN-ALWAYS = | ||||||
| 112_backtrace.test: FLAGS += -dt -b | 112_backtrace.test: FLAGS += -dt -b | ||||||
| 112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \ | 112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \ | ||||||
|     -e 's;[0-9A-Fa-fx]\{5,\};........;g' \
 |     -e 's;[0-9A-Fa-fx]\{5,\};........;g' \
 | ||||||
|     -e 's;0x[0-9A-Fa-f]\{1,\};0x?;g' \
 |     -e 's;0x[0-9A-Fa-f]\{1,\};0x?;g' | ||||||
|     -e 's;struct copy destination;memmove dest;g' \
 |  | ||||||
| 
 | 
 | ||||||
| # this test creates two DLLs and an EXE
 | # this test creates two DLLs and an EXE
 | ||||||
| 113_btdll.test: T1 = \ | 113_btdll.test: T1 = \ | ||||||
|  |  | ||||||
							
								
								
									
										70
									
								
								x86_64-gen.c
									
										
									
									
									
								
							
							
						
						
									
										70
									
								
								x86_64-gen.c
									
										
									
									
									
								
							|  | @ -35,6 +35,8 @@ | ||||||
| #define RC_RAX     0x0004 | #define RC_RAX     0x0004 | ||||||
| #define RC_RCX     0x0008 | #define RC_RCX     0x0008 | ||||||
| #define RC_RDX     0x0010 | #define RC_RDX     0x0010 | ||||||
|  | #define RC_RSI     0x0020 | ||||||
|  | #define RC_RDI     0x0040 | ||||||
| #define RC_ST0     0x0080 /* only for long double */ | #define RC_ST0     0x0080 /* only for long double */ | ||||||
| #define RC_R8      0x0100 | #define RC_R8      0x0100 | ||||||
| #define RC_R9      0x0200 | #define RC_R9      0x0200 | ||||||
|  | @ -105,6 +107,10 @@ enum { | ||||||
| /* define if return values need to be extended explicitely
 | /* define if return values need to be extended explicitely
 | ||||||
|    at caller side (for interfacing with non-TCC compilers) */ |    at caller side (for interfacing with non-TCC compilers) */ | ||||||
| #define PROMOTE_RET | #define PROMOTE_RET | ||||||
|  | 
 | ||||||
|  | #define TCC_TARGET_NATIVE_STRUCT_COPY | ||||||
|  | ST_FUNC void gen_struct_copy(int size); | ||||||
|  | 
 | ||||||
| /******************************************************/ | /******************************************************/ | ||||||
| #else /* ! TARGET_DEFS_ONLY */ | #else /* ! TARGET_DEFS_ONLY */ | ||||||
| /******************************************************/ | /******************************************************/ | ||||||
|  | @ -124,8 +130,8 @@ ST_DATA const int reg_classes[NB_REGS] = { | ||||||
|     0, |     0, | ||||||
|     0, |     0, | ||||||
|     0, |     0, | ||||||
|     0, |     RC_RSI, | ||||||
|     0, |     RC_RDI, | ||||||
|     RC_R8, |     RC_R8, | ||||||
|     RC_R9, |     RC_R9, | ||||||
|     RC_R10, |     RC_R10, | ||||||
|  | @ -2228,7 +2234,7 @@ ST_FUNC void gen_increment_tcov (SValue *sv) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* computed goto support */ | /* computed goto support */ | ||||||
| void ggoto(void) | ST_FUNC void ggoto(void) | ||||||
| { | { | ||||||
|     gcall_or_jmp(1); |     gcall_or_jmp(1); | ||||||
|     vtop--; |     vtop--; | ||||||
|  | @ -2286,53 +2292,35 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { | ||||||
|  * Assmuing the top part of the stack looks like below, |  * Assmuing the top part of the stack looks like below, | ||||||
|  *  src dest src |  *  src dest src | ||||||
|  */ |  */ | ||||||
| void gen_struct_copy(int size) | ST_FUNC void gen_struct_copy(int size) | ||||||
| { | { | ||||||
|     save_reg(TREG_RSI); |     int n = size / PTR_SIZE; | ||||||
|     load(TREG_RSI,vtop); | #ifdef TCC_TARGET_PE | ||||||
|     vtop->r = TREG_RSI; |     o(0x5756); /* push rsi, rdi */ | ||||||
|     vswap();                    /* dest src src */ | #endif | ||||||
|     save_reg(TREG_RDI); |     gv2(RC_RDI, RC_RSI); | ||||||
|     load(TREG_RDI,vtop); |     if (n <= 4) { | ||||||
|     vtop->r = TREG_RDI; |         while (n) | ||||||
|     /*  Not aligned by 8bytes   */ |             o(0xa548), --n; | ||||||
|     if (size & 0x04) { |  | ||||||
|         o(0xa5); |  | ||||||
|     } |  | ||||||
|     if (size & 0x02) { |  | ||||||
|         o(0xa566); |  | ||||||
|     } |  | ||||||
|     if (size & 0x01) { |  | ||||||
|         o(0xa4); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     size >>= 3; |  | ||||||
|     if (!size) |  | ||||||
|         goto done; |  | ||||||
|     /*  Although this function is only called when the struct is smaller    */ |  | ||||||
|     /*  than 32 bytes(4 * PTR_SIZE),a common implementation is included     */ |  | ||||||
|     if (size <= 4 && size) { |  | ||||||
|         switch (size) { |  | ||||||
|             case 4: o(0xa548); |  | ||||||
|             case 3: o(0xa548); |  | ||||||
|             case 2: o(0xa548); |  | ||||||
|             case 1: o(0xa548); |  | ||||||
|         } |  | ||||||
|     } else { |     } else { | ||||||
|         save_reg(TREG_RCX); |         vpushi(n); | ||||||
|         vpushi(size); |         gv(RC_RCX); | ||||||
|         load(TREG_RCX,vtop); |  | ||||||
|         vtop->r = TREG_RCX; |  | ||||||
|         o(0xa548f3); |         o(0xa548f3); | ||||||
|         vpop(); |         vpop(); | ||||||
|     } |     } | ||||||
| done: |     if (size & 0x04) | ||||||
|  |         o(0xa5); | ||||||
|  |     if (size & 0x02) | ||||||
|  |         o(0xa566); | ||||||
|  |     if (size & 0x01) | ||||||
|  |         o(0xa4); | ||||||
|  | #ifdef TCC_TARGET_PE | ||||||
|  |     o(0x5e5f); /* pop rdi, rsi */ | ||||||
|  | #endif | ||||||
|     vpop(); |     vpop(); | ||||||
|     vpop(); |     vpop(); | ||||||
|     return; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| /* end of x86-64 code generator */ | /* end of x86-64 code generator */ | ||||||
| /*************************************************************/ | /*************************************************************/ | ||||||
| #endif /* ! TARGET_DEFS_ONLY */ | #endif /* ! TARGET_DEFS_ONLY */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue