mirror of
https://github.com/mirror/tinycc.git
synced 2025-03-26 12:04:59 +08:00
tccasm: allow one-line prefix+op things like "rep stosb"
This commit is contained in:
parent
a25325e9be
commit
87d84b7cb8
@ -574,6 +574,11 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
|
|||||||
static int a32 = 0, o32 = 0, addr32 = 0, data32 = 0;
|
static int a32 = 0, o32 = 0, addr32 = 0, data32 = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* force synthetic ';' after prefix instruction, so we can handle */
|
||||||
|
/* one-line things like "rep stosb" instead of only "rep\nstosb" */
|
||||||
|
if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz)
|
||||||
|
unget_tok(';');
|
||||||
|
|
||||||
/* get operands */
|
/* get operands */
|
||||||
pop = ops;
|
pop = ops;
|
||||||
nb_ops = 0;
|
nb_ops = 0;
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
DEF_ASM_OP0(iret, 0xcf)
|
DEF_ASM_OP0(iret, 0xcf)
|
||||||
DEF_ASM_OP0(rsm, 0x0faa)
|
DEF_ASM_OP0(rsm, 0x0faa)
|
||||||
DEF_ASM_OP0(hlt, 0xf4)
|
DEF_ASM_OP0(hlt, 0xf4)
|
||||||
DEF_ASM_OP0(wait, 0x9b)
|
|
||||||
DEF_ASM_OP0(nop, 0x90)
|
DEF_ASM_OP0(nop, 0x90)
|
||||||
DEF_ASM_OP0(xlat, 0xd7)
|
DEF_ASM_OP0(xlat, 0xd7)
|
||||||
|
|
||||||
@ -74,6 +73,8 @@ ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA
|
|||||||
ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
|
ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
|
||||||
|
|
||||||
/* prefixes */
|
/* prefixes */
|
||||||
|
DEF_ASM_OP0(wait, 0x9b)
|
||||||
|
DEF_ASM_OP0(fwait, 0x9b)
|
||||||
#ifdef I386_ASM_16
|
#ifdef I386_ASM_16
|
||||||
DEF_ASM_OP0(a32, 0x67)
|
DEF_ASM_OP0(a32, 0x67)
|
||||||
DEF_ASM_OP0(o32, 0x66)
|
DEF_ASM_OP0(o32, 0x66)
|
||||||
@ -282,7 +283,6 @@ ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
|
|||||||
DEF_ASM_OP0(fninit, 0xdbe3)
|
DEF_ASM_OP0(fninit, 0xdbe3)
|
||||||
DEF_ASM_OP0(fnclex, 0xdbe2)
|
DEF_ASM_OP0(fnclex, 0xdbe2)
|
||||||
DEF_ASM_OP0(fnop, 0xd9d0)
|
DEF_ASM_OP0(fnop, 0xd9d0)
|
||||||
DEF_ASM_OP0(fwait, 0x9b)
|
|
||||||
|
|
||||||
/* fp load */
|
/* fp load */
|
||||||
DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
|
DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
|
||||||
|
@ -478,6 +478,24 @@ int $0x10
|
|||||||
repz
|
repz
|
||||||
repne
|
repne
|
||||||
repnz
|
repnz
|
||||||
|
nop
|
||||||
|
|
||||||
|
lock ;negl (%eax)
|
||||||
|
wait ;pushf
|
||||||
|
rep ;stosb
|
||||||
|
repe ;lodsb
|
||||||
|
repz ;cmpsb
|
||||||
|
repne;movsb
|
||||||
|
repnz;outsb
|
||||||
|
|
||||||
|
/* handle one-line prefix + ops */
|
||||||
|
lock negl (%eax)
|
||||||
|
wait pushf
|
||||||
|
rep stosb
|
||||||
|
repe lodsb
|
||||||
|
repz cmpsb
|
||||||
|
repne movsb
|
||||||
|
repnz outsb
|
||||||
|
|
||||||
invd
|
invd
|
||||||
wbinvd
|
wbinvd
|
||||||
|
@ -2132,6 +2132,27 @@ __asm__ __volatile__(
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char * strncat2(char * dest,const char * src,size_t count)
|
||||||
|
{
|
||||||
|
int d0, d1, d2, d3;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"repne scasb\n\t" /* one-line repne prefix + string op */
|
||||||
|
"decl %1\n\t"
|
||||||
|
"movl %8,%3\n"
|
||||||
|
"1:\tdecl %3\n\t"
|
||||||
|
"js 2f\n\t"
|
||||||
|
"lodsb\n\t"
|
||||||
|
"stosb\n\t"
|
||||||
|
"testb %%al,%%al\n\t"
|
||||||
|
"jne 1b\n"
|
||||||
|
"2:\txorl %2,%2\n\t"
|
||||||
|
"stosb"
|
||||||
|
: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
|
||||||
|
: "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
|
||||||
|
: "memory");
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void * memcpy1(void * to, const void * from, size_t n)
|
static inline void * memcpy1(void * to, const void * from, size_t n)
|
||||||
{
|
{
|
||||||
int d0, d1, d2;
|
int d0, d1, d2;
|
||||||
@ -2150,6 +2171,24 @@ __asm__ __volatile__(
|
|||||||
return (to);
|
return (to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void * memcpy2(void * to, const void * from, size_t n)
|
||||||
|
{
|
||||||
|
int d0, d1, d2;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"rep movsl\n\t" /* one-line rep prefix + string op */
|
||||||
|
"testb $2,%b4\n\t"
|
||||||
|
"je 1f\n\t"
|
||||||
|
"movsw\n"
|
||||||
|
"1:\ttestb $1,%b4\n\t"
|
||||||
|
"je 2f\n\t"
|
||||||
|
"movsb\n"
|
||||||
|
"2:"
|
||||||
|
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
|
||||||
|
:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
|
||||||
|
: "memory");
|
||||||
|
return (to);
|
||||||
|
}
|
||||||
|
|
||||||
static __inline__ void sigaddset1(unsigned int *set, int _sig)
|
static __inline__ void sigaddset1(unsigned int *set, int _sig)
|
||||||
{
|
{
|
||||||
__asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
|
__asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
|
||||||
@ -2199,6 +2238,10 @@ void asm_test(void)
|
|||||||
strncat1(buf, " worldXXXXX", 3);
|
strncat1(buf, " worldXXXXX", 3);
|
||||||
printf("%s\n", buf);
|
printf("%s\n", buf);
|
||||||
|
|
||||||
|
memcpy2(buf, "hello", 6);
|
||||||
|
strncat2(buf, " worldXXXXX", 3);
|
||||||
|
printf("%s\n", buf);
|
||||||
|
|
||||||
/* 'A' constraint test */
|
/* 'A' constraint test */
|
||||||
printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234));
|
printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234));
|
||||||
printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
|
printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
|
||||||
|
Loading…
Reference in New Issue
Block a user