home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / std / cplus / 1191 < prev    next >
Encoding:
Internet Message Format  |  1992-09-15  |  8.7 KB

  1. Xref: sparky comp.std.c++:1191 comp.lang.c++:13721
  2. Newsgroups: comp.std.c++,comp.lang.c++
  3. 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
  4. From: jfc@athena.mit.edu (John F Carr)
  5. Subject: Re: Exponentiation operator proposal
  6. Message-ID: <1992Sep16.005748.20420@athena.mit.edu>
  7. Sender: news@athena.mit.edu (News system)
  8. Nntp-Posting-Host: achates.mit.edu
  9. Organization: Massachusetts Institute of Technology
  10. References: <1992Sep13.193507.27813@ima.isc.com> <MATT.92Sep14225005@physics2.berkeley.edu> <1992Sep15.201801.26417@murdoch.acc.Virginia.EDU>
  11. Date: Wed, 16 Sep 1992 00:57:48 GMT
  12. Lines: 302
  13.  
  14.  
  15. I have implemented the exponentiation proposal for gcc and g++.  Here are
  16. the changes.  This was a very quick implementation, and is intended only for
  17. people to gain experience using the feature.  I am certain there are bugs
  18. and missing features.
  19.  
  20. Your line numbers may vary as the patches here are for the gcc development
  21. sources, not the 2.2.2 release.
  22.  
  23. This requires one additional library routine: double __ipow(double, int)
  24. which is like pow() except for the argument types.
  25.  
  26.  
  27.  
  28. add to expr.c:expand_expr()
  29.  
  30.  
  31.     case EXPON_EXPR:
  32.       if (target == 0)
  33.     target = gen_reg_rtx (tmode != VOIDmode
  34.                   ? tmode : TYPE_MODE (TREE_TYPE (exp)));
  35.       return expand_pow (exp, target);
  36.  
  37.  
  38. add to expr.c:
  39.  
  40.  
  41. static rtx expand_pow (exp, target)
  42. register tree exp;
  43. rtx target;
  44. {
  45.   enum machine_mode tmode;
  46.   register rtx op0, op1;
  47.   tree arg0, arg1;
  48.  
  49.   arg0 = TREE_OPERAND (exp, 0);
  50.   op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
  51.  
  52.   arg1 = TREE_OPERAND (exp, 1);
  53.   op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
  54.  
  55.   tmode = GET_MODE (target);
  56.  
  57.   /* Special case: -1 *^ j */
  58.   if (op0 == constm1_rtx
  59.       && (GET_CODE (op1) == CONST_INT
  60.       || GET_MODE_CLASS (GET_MODE (op1)) == MODE_INT))
  61.     {
  62.       enum machine_mode op1mode = (GET_CODE (op1) == CONST_INT
  63.                 ? tmode : (enum machine_mode)GET_MODE (op1));
  64. #if BITS_BIG_ENDIAN
  65.       return extract_bit_field (op1, 1, GET_MODE_BITSIZE (op1mode), 0,
  66.                 target, op1mode, tmode,
  67.                 GET_MODE_BITSIZE (op1mode),
  68.                 GET_MODE_BITSIZE (op1mode));
  69. #else
  70.       return extract_bit_field (op1, 1, 0, 0, target, op1mode, tmode,
  71.                 GET_MODE_BITSIZE (op1mode),
  72.                 GET_MODE_BITSIZE (op1mode));
  73. #endif
  74.     }
  75.  
  76.   /* Optimize small integer exponents.  */
  77.   if (GET_CODE (op1) == CONST_INT)
  78.     {
  79.       rtx tmp = op0;
  80.       switch (INTVAL (op1))
  81.     {
  82.     case 0:
  83.       return const_tiny_rtx[1][tmode];
  84.  
  85.     case 1:
  86.       return op0;
  87.  
  88.     case 3:
  89.       tmp = expand_mult (tmode, op0, op0, NULL_RTX, 0);
  90.       /* fall through */
  91.     case 2:
  92.       return expand_mult (tmode, op0, tmp, target, 0);
  93.  
  94.     case -1:
  95.       if (GET_MODE_CLASS (tmode) == MODE_FLOAT)
  96.         return expand_binop (tmode, flodiv_optab, const_tiny_rtx[1][tmode],
  97.                  op0, target, 0, OPTAB_LIB_WIDEN);
  98.     }
  99.     }
  100.  
  101.   /* For now, always pass a floating point first argument to the
  102.      library function.  */
  103.   if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE)
  104.     {
  105.       rtx tmp = gen_reg_rtx (DFmode);
  106.       expand_float (tmp, op0, 0);
  107.       op0 = tmp;
  108.     }
  109.  
  110.   if (GET_CODE (op1) == CONST_INT
  111.       || GET_MODE_CLASS (GET_MODE (op1)) == MODE_INT)
  112.     emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__ipow"), 1,
  113.                DFmode, 2, op0, DFmode, op1, SImode);
  114.   else
  115.     emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "pow"), 1,
  116.                DFmode, 2, op0, DFmode,
  117.                convert_to_mode (DFmode, op1, 0),
  118.                DFmode);
  119.  
  120.   if (GET_MODE_CLASS (GET_MODE (target)) == MODE_INT)
  121.     expand_fix (target, hard_libcall_value (DFmode), 0);
  122.   else
  123.     convert_move (target, hard_libcall_value (DFmode));
  124.  
  125.   return target;
  126. }
  127.  
  128.  
  129. add to c-typeck.c:build_binary_op and cp-typeck.c:build_binary_op_nodefault()
  130.  
  131.     case EXPON_EXPR:
  132.       /* Rules for exponent: type of result is always converted type of LHS.
  133.      If RHS is integer, no conversions.
  134.      If RHS is real and LHS is integer, convert LHS to RHS.  */
  135.  
  136.       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
  137.       && code1 == INTEGER_TYPE)
  138.     {
  139.       result_type = type0;
  140.       converted = 1;
  141.     }
  142.       else if (code0 == REAL_TYPE && code1 == REAL_TYPE)
  143.     {
  144.       result_type = type0;
  145.       converted = 1;
  146.     }
  147.       else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
  148.     {
  149.       op0 = convert (type1, op0);
  150.       result_type = type1;
  151.       converted = 1;
  152.     }
  153.       break;
  154.  
  155.  
  156. *** cp-parse.y.orig    Thu Sep  3 22:27:15 1992
  157. --- cp-parse.y    Sat Sep 12 13:11:06 1992
  158. ***************
  159. *** 190,195 ****
  160. --- 190,196 ----
  161.   %left <code> '+' '-'
  162.   %left <code> '*' '/' '%'
  163.   %right <code> UNARY PLUSPLUS MINUSMINUS
  164. + %right <code> EXPON
  165.   %left HYPERUNARY
  166.   %left <ttype> PAREN_STAR_PAREN LEFT_RIGHT
  167.   %left <code> POINTSAT POINTSAT_STAR '.' DOT_STAR '(' '['
  168. ***************
  169. *** 1209,1214 ****
  170. --- 1210,1217 ----
  171.           { $$ = build_x_binary_op ($2, $$, $3); }
  172.       | expr_no_commas '*' expr_no_commas
  173.           { $$ = build_x_binary_op ($2, $$, $3); }
  174. +     | expr_no_commas EXPON expr_no_commas
  175. +         { $$ = build_x_binary_op ($2, $$, $3); }
  176.       | expr_no_commas '/' expr_no_commas
  177.           { $$ = build_x_binary_op ($2, $$, $3); }
  178.       | expr_no_commas '%' expr_no_commas
  179. ***************
  180. *** 3736,3741 ****
  181. --- 3739,3746 ----
  182.   operator_name:
  183.         OPERATOR '*'
  184.           { $$ = ansi_opname[MULT_EXPR]; }
  185. +     | OPERATOR EXPON
  186. +         { $$ = ansi_opname[EXPON_EXPR]; }
  187.       | OPERATOR '/'
  188.           { $$ = ansi_opname[TRUNC_DIV_EXPR]; }
  189.       | OPERATOR '%'
  190.  
  191. *** c-parse.y    Wed Aug 26 20:42:25 1992
  192. --- c-parse.y    Sun Sep 13 12:30:22 1992
  193. ***************
  194. *** 130,135 ****
  195. --- 130,136 ----
  196.   %left <code> '+' '-'
  197.   %left <code> '*' '/' '%'
  198.   %right <code> UNARY PLUSPLUS MINUSMINUS
  199. + %right <code> EXPON
  200.   %left HYPERUNARY
  201.   %left <code> POINTSAT '.' '(' '['
  202.   
  203. ***************
  204. *** 402,407 ****
  205. --- 403,410 ----
  206.           { $$ = parser_build_binary_op ($2, $1, $3); }
  207.       | expr_no_commas '*' expr_no_commas
  208.           { $$ = parser_build_binary_op ($2, $1, $3); }
  209. +     | expr_no_commas EXPON expr_no_commas
  210. +         { $$ = parser_build_binary_op ($2, $$, $3); }
  211.       | expr_no_commas '/' expr_no_commas
  212.           { $$ = parser_build_binary_op ($2, $1, $3); }
  213.       | expr_no_commas '%' expr_no_commas
  214.  
  215. *** c-lex.c    Tue Sep  1 20:23:56 1992
  216. --- c-lex.c    Sun Sep 13 12:34:45 1992
  217. ***************
  218. *** 1889,1894 ****
  219. --- 1889,1910 ----
  220.           }
  221.       else if ((c == '-') && (c1 == '>'))
  222.         { value = POINTSAT; goto done; }
  223. +     else if (c == '*' && c1 == '^')
  224. +       {
  225. +         yylval.code = EXPON_EXPR;
  226. +         token_buffer[2] = c1 = getc (finput);
  227. +         if (c1 == '=')
  228. +           {
  229. +         value = ASSIGN;
  230. +         goto done;
  231. +           }
  232. +         ungetc (c1, finput);
  233. +         token_buffer[2] = 0;
  234. +         value = EXPON;
  235. +         goto done;
  236. +       }
  237.       ungetc (c1, finput);
  238.       token_buffer[1] = 0;
  239.   
  240. *** cp-lex.c.orig    Thu Sep  3 22:27:06 1992
  241. --- cp-lex.c    Sat Sep 12 13:30:12 1992
  242. ***************
  243. *** 480,485 ****
  244. --- 485,492 ----
  245.     ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
  246.     ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
  247.     ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
  248. +   ansi_opname[(int) EXPON_EXPR] = get_identifier ("__exp");
  249. +   IDENTIFIER_OPNAME_P (ansi_opname[(int) EXPON_EXPR]) = 1;
  250.     ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl");
  251.     IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1;
  252.     ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl");
  253. ***************
  254. *** 658,663 ****
  255. --- 665,671 ----
  256.     opname_tab[(int) PLUS_EXPR] = "+";
  257.     opname_tab[(int) MINUS_EXPR] = "-";
  258.     opname_tab[(int) MULT_EXPR] = "*";
  259. +   opname_tab[(int) EXPON_EXPR] = "*^";
  260.     opname_tab[(int) TRUNC_DIV_EXPR] = "/";
  261.     opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)";
  262.     opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)";
  263. ***************
  264. *** 707,712 ****
  265. --- 715,721 ----
  266.     assignop_tab[(int) MINUS_EXPR] = "-=";
  267.     assignop_tab[(int) NEGATE_EXPR] = "-=";
  268.     assignop_tab[(int) MULT_EXPR] = "*=";
  269. +   assignop_tab[(int) MULT_EXPR] = "*^=";
  270.     assignop_tab[(int) INDIRECT_REF] = "*=";
  271.     assignop_tab[(int) TRUNC_DIV_EXPR] = "/=";
  272.     assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)";
  273. ***************
  274. *** 3592,3597 ****
  275. --- 3605,3626 ----
  276.                token_buffer);
  277.           goto done;
  278.         }
  279. +     else if (c == '*' && c1 == '^')
  280. +       {
  281. +         c1 = getch ();
  282. +         yylval.code = EXPON_EXPR;
  283. +         if (c1 == '=')
  284. +           {
  285. +         value = ASSIGN;
  286. +         nextchar = -1;
  287. +           }
  288. +         else
  289. +           {
  290. +         value = EXPON;
  291. +         nextchar = c1;
  292. +           }
  293. +         goto done;
  294. +       }
  295.   
  296.       nextchar = c1;
  297.       token_buffer[1] = 0;
  298. *** c-common.c.orig    Tue Jul 28 23:46:51 1992
  299. --- c-common.c    Sat Sep 12 13:45:45 1992
  300. ***************
  301. *** 476,481 ****
  302. --- 476,483 ----
  303.       case LROTATE_EXPR:
  304.       case RROTATE_EXPR:
  305.         opname = "rotate"; break;
  306. +     case EXPON_EXPR:
  307. +       opname = "exponentiation"; break;
  308.       }
  309.     error ("invalid operands to binary %s", opname);
  310.   }
  311.  
  312. --
  313.     John Carr (jfc@athena.mit.edu)
  314.