From 8a8818104bb985fac3b8c54ae192af504348ab36 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Wed, 6 May 2009 18:08:44 +0200 Subject: [PATCH 1/3] Translate fsub/fdiv correctly. See #256. --- gen/asm-x86-32.h | 26 +++++++++++++++++++++++--- gen/asm-x86-64.h | 26 +++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/gen/asm-x86-32.h b/gen/asm-x86-32.h index b2f06c77..7d4a9545 100644 --- a/gen/asm-x86-32.h +++ b/gen/asm-x86-32.h @@ -1886,10 +1886,30 @@ namespace AsmParserx8632 } break; default: + // special case fdiv, fsub: see dmd 840, ldc 256 + if (strncmp(mnemonic, "fsub", 4) == 0 || + strncmp(mnemonic, "fdiv", 4) == 0) + { + // replace: + // f{sub,div}r{p,} <-> f{sub,div}{p,} + if (mnemonic[4] == 'r') + { + insnTemplate.write(mnemonic, 4); + insnTemplate.write(mnemonic+5, strlen(mnemonic)-5); + } + else + { + insnTemplate.write(mnemonic, 4) << "r"; + insnTemplate.write(mnemonic+4, strlen(mnemonic)-4); + } + } + else + { insnTemplate << mnemonic; - if ( type_char ) - insnTemplate << type_char; - break; + } + if ( type_char ) + insnTemplate << type_char; + break; } switch ( opInfo->implicitClobbers & Clb_DXAX_Mask ) diff --git a/gen/asm-x86-64.h b/gen/asm-x86-64.h index 3060da0c..4afdf95d 100644 --- a/gen/asm-x86-64.h +++ b/gen/asm-x86-64.h @@ -2008,10 +2008,30 @@ namespace AsmParserx8664 } break; default: + // special case fdiv, fsub: see dmd 840, ldc 256 + if (strncmp(mnemonic, "fsub", 4) == 0 || + strncmp(mnemonic, "fdiv", 4) == 0) + { + // replace: + // f{sub,div}r{p,} <-> f{sub,div}{p,} + if (mnemonic[4] == 'r') + { + insnTemplate.write(mnemonic, 4); + insnTemplate.write(mnemonic+5, strlen(mnemonic)-5); + } + else + { + insnTemplate.write(mnemonic, 4) << "r"; + insnTemplate.write(mnemonic+4, strlen(mnemonic)-4); + } + } + else + { insnTemplate << mnemonic; - if ( type_char ) - insnTemplate << type_char; - break; + } + if ( type_char ) + insnTemplate << type_char; + break; } switch ( opInfo->implicitClobbers & Clb_DXAX_Mask ) From c57f6212a6431469e32d34fff4507f452f85640d Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Wed, 6 May 2009 18:54:20 +0200 Subject: [PATCH 2/3] Make the no-operand versions of floating point inline asm instructions always pop the floating point stack - like dmd does. --- gen/asm-x86-32.h | 6 ++++++ gen/asm-x86-64.h | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/gen/asm-x86-32.h b/gen/asm-x86-32.h index 7d4a9545..b2ed99b1 100644 --- a/gen/asm-x86-32.h +++ b/gen/asm-x86-32.h @@ -1885,6 +1885,12 @@ namespace AsmParserx8632 insnTemplate.write(mnemonic, mlen-1) << tc_1 << type_char; } break; + + case Op_FMath0: + // the no-operand versions of floating point ops always pop + insnTemplate << mnemonic << "p"; + break; + default: // special case fdiv, fsub: see dmd 840, ldc 256 if (strncmp(mnemonic, "fsub", 4) == 0 || diff --git a/gen/asm-x86-64.h b/gen/asm-x86-64.h index 4afdf95d..51f0d8af 100644 --- a/gen/asm-x86-64.h +++ b/gen/asm-x86-64.h @@ -2007,6 +2007,12 @@ namespace AsmParserx8664 insnTemplate.write(mnemonic, mlen-1) << tc_1 << type_char; } break; + + case Op_FMath0: + // the no-operand versions of floating point ops always pop + insnTemplate << mnemonic << "p"; + break; + default: // special case fdiv, fsub: see dmd 840, ldc 256 if (strncmp(mnemonic, "fsub", 4) == 0 || From 108309a579f6862ee14c083ef4c74332dba99f2e Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Wed, 6 May 2009 19:56:33 +0200 Subject: [PATCH 3/3] Ignore short/long prefix of labels instead of ignoring the whole branch instruction! --- gen/asm-x86-32.h | 14 ++++---------- gen/asm-x86-64.h | 16 ++++------------ 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/gen/asm-x86-32.h b/gen/asm-x86-32.h index b2ed99b1..f82ca750 100644 --- a/gen/asm-x86-32.h +++ b/gen/asm-x86-32.h @@ -1419,12 +1419,6 @@ namespace AsmParserx8632 { nextToken(); } - else if ( token->value == TOKint16 || token->value == TOKint32 ) - { - //throw away the 'short' in "jle short label;". Works for 'long' also. - operands[0] = operands[1]; - return; - } else if ( token->value != TOKeof ) { ok = false; @@ -2741,6 +2735,10 @@ namespace AsmParserx8632 Expression * e; Identifier * ident = NULL; + // get rid of short/long prefixes for branches + if (opTakesLabel() && (token->value == TOKint16 || token->value == TOKint64)) + nextToken(); + switch ( token->value ) { case TOKint32v: @@ -2887,10 +2885,6 @@ namespace AsmParserx8632 ident = Id::__dollar; goto do_dollar; break; - case TOKint16: - case TOKint32: - //This if for the 'short' in "jle short Label;" - return Handled; default: if ( op == Op_FMath0 || op == Op_FdST0ST1 || op == Op_FMath ) return Handled; diff --git a/gen/asm-x86-64.h b/gen/asm-x86-64.h index 51f0d8af..a895f261 100644 --- a/gen/asm-x86-64.h +++ b/gen/asm-x86-64.h @@ -1541,12 +1541,6 @@ namespace AsmParserx8664 { nextToken(); } - else if ( token->value == TOKint16 || token->value == TOKint32 || token->value == TOKint64 ) - { - //throw away the 'short' in "jle short Label;". Works for long also. - operands[0] = operands[1]; - return; - } else if ( token->value != TOKeof ) { ok = false; @@ -2864,6 +2858,10 @@ namespace AsmParserx8664 Expression * e; Identifier * ident = NULL; + // get rid of short/long prefixes for branches + if (opTakesLabel() && (token->value == TOKint16 || token->value == TOKint64)) + nextToken(); + switch ( token->value ) { case TOKint32v: @@ -3010,12 +3008,6 @@ namespace AsmParserx8664 ident = Id::__dollar; goto do_dollar; break; - case TOKint16: - case TOKint32: - case TOKint64: - //This is for the 'short' in "jle short Label;" - return Handled; - break; default: if ( op == Op_FMath0 || op == Op_FdST0ST1 || op == Op_FMath ) return Handled;