Article View: comp.std.c++
Article #177Re: Exponentiation operator proposal
From: John F Carr
Date: Wed, 16 Sep 1992 00:57
Date: Wed, 16 Sep 1992 00:57
302 lines
9135 bytes
9135 bytes
I have implemented the exponentiation proposal for gcc and g++. Here are
the changes. This was a very quick implementation, and is intended only for
people to gain experience using the feature. I am certain there are bugs
and missing features.
Your line numbers may vary as the patches here are for the gcc development
sources, not the 2.2.2 release.
This requires one additional library routine: double __ipow(double, int)
which is like pow() except for the argument types.
add to expr.c:expand_expr()
case EXPON_EXPR:
if (target == 0)
target = gen_reg_rtx (tmode != VOIDmode
? tmode : TYPE_MODE (TREE_TYPE (exp)));
return expand_pow (exp, target);
add to expr.c:
static rtx expand_pow (exp, target)
register tree exp;
rtx target;
{
enum machine_mode tmode;
register rtx op0, op1;
tree arg0, arg1;
arg0 = TREE_OPERAND (exp, 0);
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
arg1 = TREE_OPERAND (exp, 1);
op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
tmode = GET_MODE (target);
/* Special case: -1 *^ j */
if (op0 == constm1_rtx
&& (GET_CODE (op1) == CONST_INT
|| GET_MODE_CLASS (GET_MODE (op1)) == MODE_INT))
{
enum machine_mode op1mode = (GET_CODE (op1) == CONST_INT
? tmode : (enum machine_mode)GET_MODE (op1));
#if BITS_BIG_ENDIAN
return extract_bit_field (op1, 1, GET_MODE_BITSIZE (op1mode), 0,
target, op1mode, tmode,
GET_MODE_BITSIZE (op1mode),
GET_MODE_BITSIZE (op1mode));
#else
return extract_bit_field (op1, 1, 0, 0, target, op1mode, tmode,
GET_MODE_BITSIZE (op1mode),
GET_MODE_BITSIZE (op1mode));
#endif
}
/* Optimize small integer exponents. */
if (GET_CODE (op1) == CONST_INT)
{
rtx tmp = op0;
switch (INTVAL (op1))
{
case 0:
return const_tiny_rtx[1][tmode];
case 1:
return op0;
case 3:
tmp = expand_mult (tmode, op0, op0, NULL_RTX, 0);
/* fall through */
case 2:
return expand_mult (tmode, op0, tmp, target, 0);
case -1:
if (GET_MODE_CLASS (tmode) == MODE_FLOAT)
return expand_binop (tmode, flodiv_optab, const_tiny_rtx[1][tmode],
op0, target, 0, OPTAB_LIB_WIDEN);
}
}
/* For now, always pass a floating point first argument to the
library function. */
if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE)
{
rtx tmp = gen_reg_rtx (DFmode);
expand_float (tmp, op0, 0);
op0 = tmp;
}
if (GET_CODE (op1) == CONST_INT
|| GET_MODE_CLASS (GET_MODE (op1)) == MODE_INT)
emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__ipow"), 1,
DFmode, 2, op0, DFmode, op1, SImode);
else
emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "pow"), 1,
DFmode, 2, op0, DFmode,
convert_to_mode (DFmode, op1, 0),
DFmode);
if (GET_MODE_CLASS (GET_MODE (target)) == MODE_INT)
expand_fix (target, hard_libcall_value (DFmode), 0);
else
convert_move (target, hard_libcall_value (DFmode));
return target;
}
add to c-typeck.c:build_binary_op and cp-typeck.c:build_binary_op_nodefault()
case EXPON_EXPR:
/* Rules for exponent: type of result is always converted type of LHS.
If RHS is integer, no conversions.
If RHS is real and LHS is integer, convert LHS to RHS. */
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
&& code1 == INTEGER_TYPE)
{
result_type = type0;
converted = 1;
}
else if (code0 == REAL_TYPE && code1 == REAL_TYPE)
{
result_type = type0;
converted = 1;
}
else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
{
op0 = convert (type1, op0);
result_type = type1;
converted = 1;
}
break;
*** cp-parse.y.orig Thu Sep 3 22:27:15 1992
--- cp-parse.y Sat Sep 12 13:11:06 1992
***************
*** 190,195 ****
--- 190,196 ----
%left <code> '+' '-'
%left <code> '*' '/' '%'
%right <code> UNARY PLUSPLUS MINUSMINUS
+ %right <code> EXPON
%left HYPERUNARY
%left <ttype> PAREN_STAR_PAREN LEFT_RIGHT
%left <code> POINTSAT POINTSAT_STAR '.' DOT_STAR '(' '['
***************
*** 1209,1214 ****
--- 1210,1217 ----
{ $$ = build_x_binary_op ($2, $$, $3); }
| expr_no_commas '*' expr_no_commas
{ $$ = build_x_binary_op ($2, $$, $3); }
+ | expr_no_commas EXPON expr_no_commas
+ { $$ = build_x_binary_op ($2, $$, $3); }
| expr_no_commas '/' expr_no_commas
{ $$ = build_x_binary_op ($2, $$, $3); }
| expr_no_commas '%' expr_no_commas
***************
*** 3736,3741 ****
--- 3739,3746 ----
operator_name:
OPERATOR '*'
{ $$ = ansi_opname[MULT_EXPR]; }
+ | OPERATOR EXPON
+ { $$ = ansi_opname[EXPON_EXPR]; }
| OPERATOR '/'
{ $$ = ansi_opname[TRUNC_DIV_EXPR]; }
| OPERATOR '%'
*** c-parse.y Wed Aug 26 20:42:25 1992
--- c-parse.y Sun Sep 13 12:30:22 1992
***************
*** 130,135 ****
--- 130,136 ----
%left <code> '+' '-'
%left <code> '*' '/' '%'
%right <code> UNARY PLUSPLUS MINUSMINUS
+ %right <code> EXPON
%left HYPERUNARY
%left <code> POINTSAT '.' '(' '['
***************
*** 402,407 ****
--- 403,410 ----
{ $$ = parser_build_binary_op ($2, $1, $3); }
| expr_no_commas '*' expr_no_commas
{ $$ = parser_build_binary_op ($2, $1, $3); }
+ | expr_no_commas EXPON expr_no_commas
+ { $$ = parser_build_binary_op ($2, $$, $3); }
| expr_no_commas '/' expr_no_commas
{ $$ = parser_build_binary_op ($2, $1, $3); }
| expr_no_commas '%' expr_no_commas
*** c-lex.c Tue Sep 1 20:23:56 1992
--- c-lex.c Sun Sep 13 12:34:45 1992
***************
*** 1889,1894 ****
--- 1889,1910 ----
}
else if ((c == '-') && (c1 == '>'))
{ value = POINTSAT; goto done; }
+ else if (c == '*' && c1 == '^')
+ {
+ yylval.code = EXPON_EXPR;
+ token_buffer[2] = c1 = getc (finput);
+ if (c1 == '=')
+ {
+ value = ASSIGN;
+ goto done;
+ }
+ ungetc (c1, finput);
+ token_buffer[2] = 0;
+ value = EXPON;
+ goto done;
+ }
+
+
ungetc (c1, finput);
token_buffer[1] = 0;
*** cp-lex.c.orig Thu Sep 3 22:27:06 1992
--- cp-lex.c Sat Sep 12 13:30:12 1992
***************
*** 480,485 ****
--- 485,492 ----
ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
+ ansi_opname[(int) EXPON_EXPR] = get_identifier ("__exp");
+ IDENTIFIER_OPNAME_P (ansi_opname[(int) EXPON_EXPR]) = 1;
ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl");
IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1;
ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl");
***************
*** 658,663 ****
--- 665,671 ----
opname_tab[(int) PLUS_EXPR] = "+";
opname_tab[(int) MINUS_EXPR] = "-";
opname_tab[(int) MULT_EXPR] = "*";
+ opname_tab[(int) EXPON_EXPR] = "*^";
opname_tab[(int) TRUNC_DIV_EXPR] = "/";
opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)";
opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)";
***************
*** 707,712 ****
--- 715,721 ----
assignop_tab[(int) MINUS_EXPR] = "-=";
assignop_tab[(int) NEGATE_EXPR] = "-=";
assignop_tab[(int) MULT_EXPR] = "*=";
+ assignop_tab[(int) MULT_EXPR] = "*^=";
assignop_tab[(int) INDIRECT_REF] = "*=";
assignop_tab[(int) TRUNC_DIV_EXPR] = "/=";
assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)";
***************
*** 3592,3597 ****
--- 3605,3626 ----
token_buffer);
goto done;
}
+ else if (c == '*' && c1 == '^')
+ {
+ c1 = getch ();
+ yylval.code = EXPON_EXPR;
+ if (c1 == '=')
+ {
+ value = ASSIGN;
+ nextchar = -1;
+ }
+ else
+ {
+ value = EXPON;
+ nextchar = c1;
+ }
+ goto done;
+ }
nextchar = c1;
token_buffer[1] = 0;
*** c-common.c.orig Tue Jul 28 23:46:51 1992
--- c-common.c Sat Sep 12 13:45:45 1992
***************
*** 476,481 ****
--- 476,483 ----
case LROTATE_EXPR:
case RROTATE_EXPR:
opname = "rotate"; break;
+ case EXPON_EXPR:
+ opname = "exponentiation"; break;
}
error ("invalid operands to binary %s", opname);
}
--
John Carr (jfc@athena.mit.edu)
Technical Details
Message-ID:
<1992Sep16.005748.20420@athena.mit.edu>Path:
arc1-ca.pugleaf.net!sparky!uunet!haven.umd.edu!darwin.sura.net!wupost!micro-heart-of-gold.mit.edu!mintaka.lcs.mit.edu!bloom-picayune.mit.edu!athena.mit.edu!jfcReferences:
<1992Sep13.193507.27813@ima.isc.com> <MATT.92Sep14225005@physics2.berkeley.edu> <1992Sep15.201801.26417@murdoch.acc.Virginia.EDU>Show Full Headers
Complete Article Headers
Newsgroups: comp.std.c++,comp.lang.c++ Path: arc1-ca.pugleaf.net!sparky!uunet!haven.umd.edu!darwin.sura.net!wupost!micro-heart-of-gold.mit.edu!mintaka.lcs.mit.edu!bloom-picayune.mit.edu!athena.mit.edu!jfc From: jfc@athena.mit.edu (John F Carr) Subject: Re: Exponentiation operator proposal Message-ID: <1992Sep16.005748.20420@athena.mit.edu> Sender: news@athena.mit.edu (News system) Nntp-Posting-Host: achates.mit.edu Organization: Massachusetts Institute of Technology References: <1992Sep13.193507.27813@ima.isc.com> <MATT.92Sep14225005@physics2.berkeley.edu> <1992Sep15.201801.26417@murdoch.acc.Virginia.EDU> Date: Wed, 16 Sep 1992 00:57:48 GMT Lines: 302