Unified · Split
| @@ -574,6 +574,11 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) · 573 unmodified lines | |||
| 574 | static int a32 = 0, o32 = 0, addr32 = 0, data32 = 0; | 574 | static int a32 = 0, o32 = 0, addr32 = 0, data32 = 0; |
| 575 | #endif | 575 | #endif |
| 576 | 576 | ||
| 577 | /* force synthetic ';' after prefix instruction, so we can handle */ | ||
| 578 | /* one-line things like "rep stosb" instead of only "rep\nstosb" */ | ||
| 579 | if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz) | ||
| 580 | unget_tok(';'); | ||
| 581 | |||
| 577 | /* get operands */ | 582 | /* get operands */ |
| 578 | pop = ops; | 583 | pop = ops; |
| 579 | nb_ops = 0; | 584 | nb_ops = 0; |
| @@ -33,7 +33,6 @@ · 32 unmodified lines | |||
| 33 | DEF_ASM_OP0(iret, 0xcf) | 33 | DEF_ASM_OP0(iret, 0xcf) |
| 34 | DEF_ASM_OP0(rsm, 0x0faa) | 34 | DEF_ASM_OP0(rsm, 0x0faa) |
| 35 | DEF_ASM_OP0(hlt, 0xf4) | 35 | DEF_ASM_OP0(hlt, 0xf4) |
| 36 | DEF_ASM_OP0(wait, 0x9b) | ||
| 37 | DEF_ASM_OP0(nop, 0x90) | 36 | DEF_ASM_OP0(nop, 0x90) |
| 38 | DEF_ASM_OP0(xlat, 0xd7) | 37 | DEF_ASM_OP0(xlat, 0xd7) |
| 39 | 38 | ||
| @@ -74,6 +73,8 @@ ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA · 34 unmodified lines | |||
| 74 | ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) | 73 | ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) |
| 75 | 74 | ||
| 76 | /* prefixes */ | 75 | /* prefixes */ |
| 76 | DEF_ASM_OP0(wait, 0x9b) | ||
| 77 | DEF_ASM_OP0(fwait, 0x9b) | ||
| 77 | #ifdef I386_ASM_16 | 78 | #ifdef I386_ASM_16 |
| 78 | DEF_ASM_OP0(a32, 0x67) | 79 | DEF_ASM_OP0(a32, 0x67) |
| 79 | DEF_ASM_OP0(o32, 0x66) | 80 | DEF_ASM_OP0(o32, 0x66) |
| @@ -282,7 +283,6 @@ ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) · 202 unmodified lines | |||
| 282 | DEF_ASM_OP0(fninit, 0xdbe3) | 283 | DEF_ASM_OP0(fninit, 0xdbe3) |
| 283 | DEF_ASM_OP0(fnclex, 0xdbe2) | 284 | DEF_ASM_OP0(fnclex, 0xdbe2) |
| 284 | DEF_ASM_OP0(fnop, 0xd9d0) | 285 | DEF_ASM_OP0(fnop, 0xd9d0) |
| 285 | DEF_ASM_OP0(fwait, 0x9b) | ||
| 286 | 286 | ||
| 287 | /* fp load */ | 287 | /* fp load */ |
| 288 | DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) | 288 | DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) |
| @@ -478,6 +478,24 @@ int $0x10 · 477 unmodified lines | |||
| 478 | repz | 478 | repz |
| 479 | repne | 479 | repne |
| 480 | repnz | 480 | repnz |
| 481 | nop | ||
| 482 | |||
| 483 | lock ;negl (%eax) | ||
| 484 | wait ;pushf | ||
| 485 | rep ;stosb | ||
| 486 | repe ;lodsb | ||
| 487 | repz ;cmpsb | ||
| 488 | repne;movsb | ||
| 489 | repnz;outsb | ||
| 490 | |||
| 491 | /* handle one-line prefix + ops */ | ||
| 492 | lock negl (%eax) | ||
| 493 | wait pushf | ||
| 494 | rep stosb | ||
| 495 | repe lodsb | ||
| 496 | repz cmpsb | ||
| 497 | repne movsb | ||
| 498 | repnz outsb | ||
| 481 | 499 | ||
| 482 | invd | 500 | invd |
| 483 | wbinvd | 501 | wbinvd |
| @@ -2132,6 +2132,27 @@ __asm__ __volatile__( · 2131 unmodified lines | |||
| 2132 | return dest; | 2132 | return dest; |
| 2133 | } | 2133 | } |
| 2134 | 2134 | ||
| 2135 | static char * strncat2(char * dest,const char * src,size_t count) | ||
| 2136 | { | ||
| 2137 | int d0, d1, d2, d3; | ||
| 2138 | __asm__ __volatile__( | ||
| 2139 | "repne scasb\n\t" /* one-line repne prefix + string op */ | ||
| 2140 | "decl %1\n\t" | ||
| 2141 | "movl %8,%3\n" | ||
| 2142 | "1:\tdecl %3\n\t" | ||
| 2143 | "js 2f\n\t" | ||
| 2144 | "lodsb\n\t" | ||
| 2145 | "stosb\n\t" | ||
| 2146 | "testb %%al,%%al\n\t" | ||
| 2147 | "jne 1b\n" | ||
| 2148 | "2:\txorl %2,%2\n\t" | ||
| 2149 | "stosb" | ||
| 2150 | : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) | ||
| 2151 | : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) | ||
| 2152 | : "memory"); | ||
| 2153 | return dest; | ||
| 2154 | } | ||
| 2155 | |||
| 2135 | static inline void * memcpy1(void * to, const void * from, size_t n) | 2156 | static inline void * memcpy1(void * to, const void * from, size_t n) |
| 2136 | { | 2157 | { |
| 2137 | int d0, d1, d2; | 2158 | int d0, d1, d2; |
| @@ -2150,6 +2171,24 @@ __asm__ __volatile__( · 12 unmodified lines | |||
| 2150 | return (to); | 2171 | return (to); |
| 2151 | } | 2172 | } |
| 2152 | 2173 | ||
| 2174 | static inline void * memcpy2(void * to, const void * from, size_t n) | ||
| 2175 | { | ||
| 2176 | int d0, d1, d2; | ||
| 2177 | __asm__ __volatile__( | ||
| 2178 | "rep movsl\n\t" /* one-line rep prefix + string op */ | ||
| 2179 | "testb $2,%b4\n\t" | ||
| 2180 | "je 1f\n\t" | ||
| 2181 | "movsw\n" | ||
| 2182 | "1:\ttestb $1,%b4\n\t" | ||
| 2183 | "je 2f\n\t" | ||
| 2184 | "movsb\n" | ||
| 2185 | "2:" | ||
| 2186 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) | ||
| 2187 | :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) | ||
| 2188 | : "memory"); | ||
| 2189 | return (to); | ||
| 2190 | } | ||
| 2191 | |||
| 2153 | static __inline__ void sigaddset1(unsigned int *set, int _sig) | 2192 | static __inline__ void sigaddset1(unsigned int *set, int _sig) |
| 2154 | { | 2193 | { |
| 2155 | __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); | 2194 | __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); |
| @@ -2199,6 +2238,10 @@ void asm_test(void) · 43 unmodified lines | |||
| 2199 | strncat1(buf, " worldXXXXX", 3); | 2238 | strncat1(buf, " worldXXXXX", 3); |
| 2200 | printf("%s\n", buf); | 2239 | printf("%s\n", buf); |
| 2201 | 2240 | ||
| 2241 | memcpy2(buf, "hello", 6); | ||
| 2242 | strncat2(buf, " worldXXXXX", 3); | ||
| 2243 | printf("%s\n", buf); | ||
| 2244 | |||
| 2202 | /* 'A' constraint test */ | 2245 | /* 'A' constraint test */ |
| 2203 | printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234)); | 2246 | printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234)); |
| 2204 | printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff)); | 2247 | printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff)); |