Unified · Split
| @@ -574,6 +574,11 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) · 573 unmodified lines | ||
| 574 | 574 | static int a32 = 0, o32 = 0, addr32 = 0, data32 = 0; |
| 575 | 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 | 582 | /* get operands */ |
| 578 | 583 | pop = ops; |
| 579 | 584 | nb_ops = 0; |
| @@ -33,7 +33,6 @@ · 32 unmodified lines | ||
| 33 | 33 | DEF_ASM_OP0(iret, 0xcf) |
| 34 | 34 | DEF_ASM_OP0(rsm, 0x0faa) |
| 35 | 35 | DEF_ASM_OP0(hlt, 0xf4) |
| 36 | − DEF_ASM_OP0(wait, 0x9b) | |
| 37 | 36 | DEF_ASM_OP0(nop, 0x90) |
| 38 | 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 | 73 | ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) |
| 75 | 74 | |
| 76 | 75 | /* prefixes */ |
| 76 | + DEF_ASM_OP0(wait, 0x9b) | |
| 77 | + DEF_ASM_OP0(fwait, 0x9b) | |
| 77 | 78 | #ifdef I386_ASM_16 |
| 78 | 79 | DEF_ASM_OP0(a32, 0x67) |
| 79 | 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 | 283 | DEF_ASM_OP0(fninit, 0xdbe3) |
| 283 | 284 | DEF_ASM_OP0(fnclex, 0xdbe2) |
| 284 | 285 | DEF_ASM_OP0(fnop, 0xd9d0) |
| 285 | − DEF_ASM_OP0(fwait, 0x9b) | |
| 286 | 286 | |
| 287 | 287 | /* fp load */ |
| 288 | 288 | DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) |
| @@ -478,6 +478,24 @@ int $0x10 · 477 unmodified lines | ||
| 478 | 478 | repz |
| 479 | 479 | repne |
| 480 | 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 | 500 | invd |
| 483 | 501 | wbinvd |
| @@ -2132,6 +2132,27 @@ __asm__ __volatile__( · 2131 unmodified lines | ||
| 2132 | 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 | 2156 | static inline void * memcpy1(void * to, const void * from, size_t n) |
| 2136 | 2157 | { |
| 2137 | 2158 | int d0, d1, d2; |
| @@ -2150,6 +2171,24 @@ __asm__ __volatile__( · 12 unmodified lines | ||
| 2150 | 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 | 2192 | static __inline__ void sigaddset1(unsigned int *set, int _sig) |
| 2154 | 2193 | { |
| 2155 | 2194 | __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); |
| @@ -2199,6 +2238,10 @@ void asm_test(void) · 43 unmodified lines | ||
| 2199 | 2238 | strncat1(buf, " worldXXXXX", 3); |
| 2200 | 2239 | printf("%s\n", buf); |
| 2201 | 2240 | |
| 2241 | + memcpy2(buf, "hello", 6); | |
| 2242 | + strncat2(buf, " worldXXXXX", 3); | |
| 2243 | + printf("%s\n", buf); | |
| 2244 | + | |
| 2202 | 2245 | /* 'A' constraint test */ |
| 2203 | 2246 | printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234)); |
| 2204 | 2247 | printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff)); |