Sender: bill AT taniwha DOT tssc DOT co DOT nz Message-ID: <36FA139C.10675076@taniwha.tssc.co.nz> Date: Thu, 25 Mar 1999 22:44:44 +1200 From: Bill Currie X-Mailer: Mozilla 4.05 [en] (X11; I; Linux 2.2.3 i486) MIME-Version: 1.0 To: "djgpp-workers AT delorie DOT com" Subject: new-replacement djasm patch Content-Type: multipart/mixed; boundary="------------31397C6C871D4AD7CE9DBAC7" Reply-To: djgpp-workers AT delorie DOT com This is a multi-part message in MIME format. --------------31397C6C871D4AD7CE9DBAC7 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This patch is *instead* of my previous patch as that one has not been committed at this time. changes from previous patch: o sh[lr]dl is now sh[lr]dd or optionally sh[lr]dq for64 bit shifts (sh[lr]dd can be used for either 32 or 64 bit shifts) o a usefull error message is printed if sh[lr]d is used for a double shift. o shift double now supports memory destinations. Thanks, DJ, for the suggestion of `shldd' and `shldq' (and the `r' versions). I made the `q' version optional since I find it confusing as I stated earlier. Now I can go put enum support in djasm and get started on an elf loader stub (I've got the elf spec and HJ Lu's Elf doc). Should be fun. BTW, anyone know of a Lyx(or latex)->texinfo converter? I'll have to ask the Lyx people. (I'm currenly writing the djasm docs using Lyx, but I imagine texinfo is wanted) Bill -- Leave others their otherness. --------------31397C6C871D4AD7CE9DBAC7 Content-Type: text/plain; charset=us-ascii; name="djasm.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="djasm.diff" *** src/stub/djasm.y Wed Jul 29 05:14:32 1998 --- ../djasm/djasm.y Thu Mar 25 22:19:09 1999 *************** *** 34,39 **** --- 33,39 ---- void djerror(char *s); void yyerror(char *s); + void shld_error(int opcode, int b32); #define OUT_exe 0 #define OUT_com 1 *************** *** 227,233 **** %token ARITH2 ARITH2B ARITH2D ARITH2W %token LXS MOVSZX MOVSZXB MOVSZXW %token JCC JCCL JCXZ LOOP SETCC ! %token SHIFT SHLRD %token ONEBYTE TWOBYTE ASCADJ %token BITTEST GROUP3 GROUP3B GROUP3D GROUP3W GROUP6 GROUP7 STRUCT %token ALIGN ARPL --- 227,233 ---- %token ARITH2 ARITH2B ARITH2D ARITH2W %token LXS MOVSZX MOVSZXB MOVSZXW %token JCC JCCL JCXZ LOOP SETCC ! %token SHIFT SHIFTB SHIFTD SHIFTW SHLRD SHLRDQ %token ONEBYTE TWOBYTE ASCADJ %token BITTEST GROUP3 GROUP3B GROUP3D GROUP3W GROUP6 GROUP7 STRUCT %token ALIGN ARPL *************** *** 517,530 **** --- 517,545 ---- {"pushw", PUSHW, NO_ATTR}, {"pushd", PUSHD, NO_ATTR}, {"rcl", SHIFT, 2}, + {"rclb", SHIFTB, 2}, + {"rcld", SHIFTD, 2}, + {"rclw", SHIFTW, 2}, {"rcr", SHIFT, 3}, + {"rcrb", SHIFTB, 3}, + {"rcrd", SHIFTD, 3}, + {"rcrw", SHIFTW, 3}, {"ret", RET, NO_ATTR}, {"retd", RETD, NO_ATTR}, {"retf", RETF, NO_ATTR}, {"retfd", RETFD, NO_ATTR}, {"rol", SHIFT, 0}, + {"rolb", SHIFTB, 0}, + {"rold", SHIFTD, 0}, + {"rolw", SHIFTW, 0}, {"ror", SHIFT, 1}, + {"rorb", SHIFTB, 1}, + {"rord", SHIFTD, 1}, + {"rorw", SHIFTW, 1}, {"sar", SHIFT, 7}, + {"sarb", SHIFTB, 7}, + {"sard", SHIFTD, 7}, + {"sarw", SHIFTW, 7}, {"sbb", ARITH2, 3}, {"sbbb", ARITH2B, 3}, {"sbbd", ARITH2D, 3}, *************** *** 565,574 **** {"sidt", GROUP7, 1}, {"sldt", GROUP6, 0}, {"sal", SHIFT, 4}, {"shl", SHIFT, 4}, ! {"shld", SHLRD, 0xa4}, {"shr", SHIFT, 5}, ! {"shrd", SHLRD, 0xac}, {"smsw", GROUP7, 4}, {"str", GROUP6, 1}, {"sub", ARITH2, 5}, --- 580,600 ---- {"sidt", GROUP7, 1}, {"sldt", GROUP6, 0}, {"sal", SHIFT, 4}, + {"salb", SHIFTB, 4}, + {"sald", SHIFTD, 4}, + {"salw", SHIFTW, 4}, {"shl", SHIFT, 4}, ! {"shlb", SHIFTB, 4}, ! {"shld", SHIFTD, 4}, ! {"shlw", SHIFTW, 4}, ! {"shldd", SHLRD, 0xa4}, ! {"shldq", SHLRDQ, 0xa4}, {"shr", SHIFT, 5}, ! {"shrb", SHIFTB, 5}, ! {"shrd", SHIFTD, 5}, ! {"shrw", SHIFTW, 5}, ! {"shrdd", SHLRD, 0xac}, ! {"shrdq", SHLRDQ, 0xac}, {"smsw", GROUP7, 4}, {"str", GROUP6, 1}, {"sub", ARITH2, 5}, *************** *** 997,1017 **** --- 1023,1090 ---- | SHIFT REG8 ',' const { emitb($4 == 1 ? 0xd0 : 0xc0); modrm(3, $1, $2); if ($4 != 1) emitb($4); } | SHIFT REG8 ',' REG8 { if ($4 != 1) djerror ("Non-constant shift count must be `cl'"); emitb(0xd2); modrm(3, $1, $2); } + | SHIFTB regmem ',' const { emitb($4 == 1 ? 0xd0 : 0xc0); reg($1); if ($4 != 1) emitb($4); } + | SHIFTB regmem ',' REG8 { if ($4 != 1) djerror ("Non-constant shift count must be `cl'"); emitb(0xd2); reg($1); } | SHIFT REG16 ',' const { emitb($4 == 1 ? 0xd1 : 0xc1); modrm(3, $1, $2); if ($4 != 1) emitb($4); } | SHIFT REG16 ',' REG8 { if ($4 != 1) djerror ("Non-constant shift count must be `cl'"); emitb(0xd3); modrm(3, $1, $2); } + | SHIFTW regmem ',' const { emitb($4 == 1 ? 0xd1 : 0xc1); reg($1); if ($4 != 1) emitb($4); } + | SHIFTW regmem ',' REG8 { if ($4 != 1) djerror ("Non-constant shift count must be `cl'"); emitb(0xd3); reg($1); } | SHIFT REG32 ',' const { emitb(0x66); emitb($4 == 1 ? 0xd1 : 0xc1); modrm(3, $1, $2); if ($4 != 1) emitb($4); } | SHIFT REG32 ',' REG8 { if ($4 != 1) djerror ("Non-constant shift count must be `cl'"); emitb(0x66); emitb(0xd3); modrm(3, $1, $2); } + | SHIFTD regmem ',' const { emitb(0x66); emitb($4 == 1 ? 0xd1 : 0xc1); reg($1); if ($4 != 1) emitb($4); } + | SHIFTD regmem ',' REG8 { if ($4 != 1) djerror ("Non-constant shift count must be `cl'"); emitb(0x66); emitb(0xd3); reg($1); } + /* Unfortunatly, djasm's method of specifying memory operand size causes + a clash when it comes to shifs: ie Intel's shl dword ptr [mem],8 would + be (in djasm) shld [mem],8, which is the same as Intel's shift left + double (ie 64 bit shift for 32 bit operands). I don't like the idea of + overloading the meaning of instructions as assembly is hard enough to + read as it is, so flag the overloaded usage as an error recommending + the appropriate instruction to use. */ + | SHIFTD REG16 ',' REG16 ',' const { shld_error($1,0); } + | SHIFTD REG16 ',' REG16 ',' REG8 { shld_error($1,0); } + | SHIFTD regmem ',' REG16 ',' const { shld_error($1,0); } + | SHIFTD regmem ',' REG16 ',' REG8 { shld_error($1,0); } + | SHIFTD REG32 ',' REG32 ',' const { shld_error($1,1); } + | SHIFTD REG32 ',' REG32 ',' REG8 { shld_error($1,1); } + | SHIFTD regmem ',' REG32 ',' const { shld_error($1,1); } + | SHIFTD regmem ',' REG32 ',' REG8 { shld_error($1,1); } + + /* 16 bit shift double (ie 32 bit shift). */ | SHLRD REG16 ',' REG16 ',' const { emitb(0x0f); emitb($1); modrm(3, $4, $2); emitb($6); } | SHLRD REG16 ',' REG16 ',' REG8 { if ($6 != 1) djerror ("Non-constant shift count must be `cl'"); emitb(0x0f); emitb($1+1); modrm(3, $4, $2); } + | SHLRD regmem ',' REG16 ',' const + { emitb(0x0f); emitb($1); reg($4); emitb($6); } + | SHLRD regmem ',' REG16 ',' REG8 + { if ($6 != 1) djerror ("Non-constant shift count must be `cl'"); + emitb(0x0f); emitb($1+1); reg($4); } + + /* 32 bit shift double (ie 64 bit shift), can be either + `shldd'/`shrdd' or `shldq'/'shrdq' */ | SHLRD REG32 ',' REG32 ',' const { emitb(0x66); emitb(0x0f); emitb($1); modrm(3, $4, $2); emitb($6); } | SHLRD REG32 ',' REG32 ',' REG8 { if ($6 != 1) djerror ("Non-constant shift count must be `cl'"); emitb(0x66); emitb(0x0f); emitb($1+1); modrm(3, $4, $2); } + | SHLRD regmem ',' REG32 ',' const + { emitb(0x66); emitb(0x0f); emitb($1); reg($4); emitb($6); } + | SHLRD regmem ',' REG32 ',' REG8 + { if ($6 != 1) djerror ("Non-constant shift count must be `cl'"); + emitb(0x66); emitb(0x0f); emitb($1+1); reg($4); } + /* alias */ + | SHLRDQ REG32 ',' REG32 ',' const + { emitb(0x66); emitb(0x0f); emitb($1); modrm(3, $4, $2); emitb($6); } + | SHLRDQ REG32 ',' REG32 ',' REG8 + { if ($6 != 1) djerror ("Non-constant shift count must be `cl'"); + emitb(0x66); emitb(0x0f); emitb($1+1); modrm(3, $4, $2); } + | SHLRDQ regmem ',' REG32 ',' const + { emitb(0x66); emitb(0x0f); emitb($1); reg($4); emitb($6); } + | SHLRDQ regmem ',' REG32 ',' REG8 + { if ($6 != 1) djerror ("Non-constant shift count must be `cl'"); + emitb(0x66); emitb(0x0f); emitb($1+1); reg($4); } | STACK { stack_ptr = pc; } | START { start_ptr = pc; main_obj=1; } *************** *** 1240,1245 **** --- 1313,1319 ---- | '-' const { $$ = -$2; } | { $$ = 0; } ; + %% /***********************************************************************/ typedef struct FileStack { *************** *** 1364,1371 **** time(&now); sprintf(exe+28, "\r\n%s generated from %s by djasm, on %.24s\r\n", argv[2], argv[1], ctime(&now)); if (copyright) ! strncat(exe+36, copyright, 476-strlen(exe+36)); ! strcat(exe+36, "\r\n\032"); if (argv[2] == 0) { --- 1438,1445 ---- time(&now); sprintf(exe+28, "\r\n%s generated from %s by djasm, on %.24s\r\n", argv[2], argv[1], ctime(&now)); if (copyright) ! strncat(exe+28, copyright, 480-strlen(exe+28)); ! strcat(exe+28, "\r\n\032"); if (argv[2] == 0) { *************** *** 1575,1580 **** --- 1649,1676 ---- { djerror(s); fprintf(stderr, "%s:%d: Last token was `%s' (%s)\n", inname, lineno, last_token, yytname[(unsigned char)yytranslate[last_tret]]); + } + + void shld_error(int opcode, int b32) + { + char *bad_op; + char *good_op; + char msg[80]; + + if (opcode==4) + { + bad_op="`shld'"; + good_op=b32?"`shldd' or `shldq'":"`shldd'"; + } + else + { + bad_op="`shrd'"; + good_op=b32?"`shrdd' or `shrdq'":"`shrdd'"; + } + sprintf(msg,"Attempted overloaded use of %s detected.",bad_op); + djerror(msg); + sprintf(msg,"Use %s instead.",good_op); + djerror(msg); } Symbol *get_symbol(char *name, int create) --------------31397C6C871D4AD7CE9DBAC7--