home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.std.c++:1191 comp.lang.c++:13721
- Newsgroups: comp.std.c++,comp.lang.c++
- Path: 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
-
-
- 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)
-