changeset 25:2476ed92181e

modified machine description of i386 for support indirect sibcall attributed fastcall.
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Tue, 27 Oct 2009 16:04:06 +0900
parents f37d7058d1ce
children b388631e4738
files CbC-examples/quicksort/Makefile CbC-examples/quicksort/quicksort_cbc.cbc CbC-examples/quicksort/quicksort_test.cbc gcc/c-parser.c gcc/cbc-goto.h gcc/cbc-tree-debug.c gcc/config/i386/i386.c gcc/config/i386/i386.md
diffstat 8 files changed, 114 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/CbC-examples/quicksort/Makefile	Thu Oct 15 18:47:39 2009 +0900
+++ b/CbC-examples/quicksort/Makefile	Tue Oct 27 16:04:06 2009 +0900
@@ -1,8 +1,16 @@
-CbCC=../../../build_cbc44/INSTALL_DIR/bin/gcc
-CC=gcc
+
+#CbCC=../../../build_cbc44/INSTALL_DIR/bin/gcc
+CbCC=../../../build_cbc44_fast/INSTALL_DIR/bin/gcc
+
+#CC=gcc
+#CC=../../../build_cbc44/INSTALL_DIR/bin/gcc
+CC=../../../build_cbc44_fast/INSTALL_DIR/bin/gcc
+
 HEADERMAKER=../../CbC-scripts/make_headers.py
 
-CFLAGS=-g -O2
+# fastcall版では-O0,-O2は動作確認、-O3以上はだめ
+CFLAGS=-g -O2 -fomit-frame-pointer
+#CFLAGS=-g -O0
 
 .SUFFIXES: .cbc .o
 
@@ -18,13 +26,13 @@
 quicksort_test.o: quicksort_test.h
 
 quicksort_cbc: quicksort_cbc.o quicksort_test.o
-	$(CC) -o $@ $^
+	$(CC) $(CFLAGS) -o $@ $^
 quicksort_cbc2: quicksort_cbc2.o quicksort_test.o
-	$(CC) -o $@ $^
+	$(CC) $(CFLAGS) -o $@ $^
 
 quicksort_c: quicksort_c.o
-	$(CC) -o $@ $^
+	$(CC) $(CFLAGS) -o $@ $^
 
 
 clean: 
-	rm -rf *.o quicksort_c quicksort_cbc
+	rm -rf *.o *.s quicksort_c quicksort_cbc quicksort_cbc2 
--- a/CbC-examples/quicksort/quicksort_cbc.cbc	Thu Oct 15 18:47:39 2009 +0900
+++ b/CbC-examples/quicksort/quicksort_cbc.cbc	Tue Oct 27 16:04:06 2009 +0900
@@ -6,7 +6,7 @@
 typedef struct {
 	int size;
 	void *interface;
-	__code (*code)(void*, stack);
+	__code  (*code)(void*, stack) ;
 } frame, *framep;
 
 /* quickstart main routine. */
@@ -15,21 +15,21 @@
 	int s;
 	int e;
 } QS_IF ;
-typedef __code (*RET)(void*);
+typedef __code  (*RET)(void*);
 
 #include"quicksort_cbc.h"
 
 /* for check. */
 void *mustbefreed;
 
-__code returner(stack sp)
+__code  returner(stack sp)
 {
 	framep fp = (framep)sp;
 	sp += fp->size;
 	goto fp->code(fp->interface, sp);
 }
 
-__code quicksort_start(void *arg, stack sp)
+__code  quicksort_start(void *arg, stack sp)
 {
 	QS_IF *recvif = arg;
 	int a,b,c,p;
@@ -61,11 +61,11 @@
 /* main routine end. */
 
 /* divide routine. */
-__code quicksort_divider(QS_IF *recvif, int s, int e, int p, stack sp)
+__code  quicksort_divider(QS_IF *recvif, int s, int e, int p, stack sp)
 {
 	goto quicksort_divider_s(recvif, s, e, p, sp);
 }
-__code quicksort_divider_s(QS_IF *recvif, int s, int e, int p, stack sp)
+__code  quicksort_divider_s(QS_IF *recvif, int s, int e, int p, stack sp)
 {
 	if (recvif->v[s]<p) {
 		s++;
@@ -73,7 +73,7 @@
 	} else
 		goto quicksort_divider_e(recvif, s, e, p, sp);
 }
-__code quicksort_divider_e(QS_IF *recvif, int s, int e, int p, stack sp)
+__code  quicksort_divider_e(QS_IF *recvif, int s, int e, int p, stack sp)
 {
 	if (p<recvif->v[e]) {
 		e--;
@@ -81,7 +81,7 @@
 	} else
 		goto quicksort_swapper(recvif, s, e, p, sp);
 }
-__code quicksort_swapper(QS_IF *recvif, int s, int e, int p, stack sp)
+__code  quicksort_swapper(QS_IF *recvif, int s, int e, int p, stack sp)
 {
 	if (s<e) {
 		int tmp;
@@ -100,7 +100,7 @@
 
 
 /* recursive call routine. */
-__code quicksort_treecall(QS_IF *recvif, int s, int e, stack sp)
+__code  quicksort_treecall(QS_IF *recvif, int s, int e, stack sp)
 {
 	framep fp;
 	QS_IF *outif;
@@ -124,17 +124,16 @@
 #define STACK_SIZE 10240
 
 typedef struct {
-	__code (*ret)(void*);
+	__code  (*ret)(void*);
 	void *ret_arg;
 	stack *sp;
 } QS_FINISH;
-__code
+__code 
 quicksort(int *v, int s, int e,  RET ret, void *arg )
 {
 	framep fp;
 	stack sp0, sp;
-	sp0 = malloc(STACK_SIZE);
-		mustbefreed = sp0;
+	sp0 = mustbefreed = malloc(STACK_SIZE);
 	sp = sp0 + STACK_SIZE;
 	QS_FINISH *finish_if;
 	QS_IF *outif;
@@ -158,11 +157,11 @@
 
 	goto quicksort_start(outif, sp);
 }
-__code
+__code 
 quicksort_finish(void *arg, stack sp)
 {
 	QS_FINISH interface = *(QS_FINISH*)arg;
-	assert(interface.sp==mustbefreed);
+	//assert(interface.sp==mustbefreed);
 	free(interface.sp);
 	goto interface.ret(interface.ret_arg);
 }
--- a/CbC-examples/quicksort/quicksort_test.cbc	Thu Oct 15 18:47:39 2009 +0900
+++ b/CbC-examples/quicksort/quicksort_test.cbc	Tue Oct 27 16:04:06 2009 +0900
@@ -5,7 +5,7 @@
 
 #include"quicksort_test.h"
 
-extern __code quicksort(int *,int,int, __code(*)(void*), void*);
+extern __code quicksort(int *,int,int, __code (*)(void*), void*);
 
 
 void
@@ -50,11 +50,12 @@
 	printf("bad region\n");
 }
 
+static int size=100;
+
 int
 main(int argc, char **argv)
 {
 	unsigned int seed=0;
-	int size=100;
 	int opt;
 
 	while ((opt = getopt(argc, argv, "s:n:")) != -1) {
@@ -92,8 +93,8 @@
 {
 	int *v = arg;
 	int b;
-	//print_array(arg, 100);
-	//b = check_sort(arg, 100);
+	//print_array(arg, size);
+	b = check_sort(arg, size);
 	if (b) {
 		printf("sorting successful!\n");
 		exit(-1);
--- a/gcc/c-parser.c	Thu Oct 15 18:47:39 2009 +0900
+++ b/gcc/c-parser.c	Tue Oct 27 16:04:06 2009 +0900
@@ -1547,9 +1547,14 @@
 	  t.spec = c_parser_peek_token (parser)->value;
 	  declspecs_add_type (specs, t);
 
+	  /*
 	  attrs = get_identifier("fastcall");
 	  attrs = build_tree_list(attrs, NULL_TREE);
 	  declspecs_add_attrs(specs, attrs);
+	  */
+	  attrs = build_tree_list (get_identifier("fastcall"), NULL_TREE);
+	  //attrs = build_tree_list (get_identifier("noreturn"), attrs);
+	  declspecs_add_attrs(specs, attrs);
 
 	  c_parser_consume_token (parser);
 	  break;
--- a/gcc/cbc-goto.h	Thu Oct 15 18:47:39 2009 +0900
+++ b/gcc/cbc-goto.h	Tue Oct 27 16:04:06 2009 +0900
@@ -218,11 +218,10 @@
      once we have started filling any specific hard regs.  */
   precompute_register_parameters (num_actuals, args, &reg_parm_seen);
 
-  /* operand[2] is environment.  */
-  if (TREE_OPERAND (exp, 2))
-    static_chain_value = expand_normal (TREE_OPERAND (exp, 2));
+  if (CALL_EXPR_STATIC_CHAIN (exp))
+      static_chain_value = expand_normal (CALL_EXPR_STATIC_CHAIN (exp));
   else
-    static_chain_value = 0;
+      static_chain_value = 0;
 
 
   /* parallel assignment  */
@@ -315,6 +314,20 @@
       emit_indirect_jump (funexp);
     }
 #endif
+  if (GET_CODE (funexp) != SYMBOL_REF)
+    {
+      push_temp_slots();
+      preserve_temp_slots(funexp);
+      /* Generate the actual call instruction.  */
+      emit_call_1 (funexp, exp, fndecl, funtype, unadjusted_args_size,
+	  adjusted_args_size.constant, struct_value_size,
+	  //next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
+	  next_arg_reg, valreg, 0, call_fusage,
+	  flags, & args_so_far);
+      pop_temp_slots();
+    }
+  else
+    {
 
   /* Generate the actual call instruction.  */
   emit_call_1 (funexp, exp, fndecl, funtype, unadjusted_args_size,
@@ -322,6 +335,7 @@
       //next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
       next_arg_reg, valreg, 0, call_fusage,
       flags, & args_so_far);
+    }
 
   /* If a non-BLKmode value is returned at the most significant end
      of a register, shift the register right by the appropriate amount
--- a/gcc/cbc-tree-debug.c	Thu Oct 15 18:47:39 2009 +0900
+++ b/gcc/cbc-tree-debug.c	Tue Oct 27 16:04:06 2009 +0900
@@ -29,3 +29,21 @@
 {
 	return DECL_NAME (t);
 }
+
+tree
+_CALL_EXPR_FN (tree t)
+{
+	return CALL_EXPR_FN (t);
+}
+
+tree
+_CALL_EXPR_ARGS (tree t)
+{
+	return CALL_EXPR_ARGS (t);
+}
+
+tree
+_CALL_EXPR_ARG (tree t, int i)
+{
+	return CALL_EXPR_ARG (t, i);
+}
--- a/gcc/config/i386/i386.c	Thu Oct 15 18:47:39 2009 +0900
+++ b/gcc/config/i386/i386.c	Tue Oct 27 16:04:06 2009 +0900
@@ -18779,6 +18779,18 @@
       fnaddr = gen_rtx_MEM (QImode, fnaddr);
     }
 
+#ifndef noCbC
+  if (pop
+	  && sibcall
+	  && !( GET_CODE (fnaddr) == MEM
+	        && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF) )
+    {
+      rtx eax = gen_rtx_REG (Pmode, AX_REG);
+      eax = copy_to_suggested_reg (XEXP (fnaddr, 0), eax, Pmode);
+      fnaddr = gen_rtx_MEM (QImode, eax);
+    }
+#endif
+
   call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
   if (retval)
     call = gen_rtx_SET (VOIDmode, retval, call);
--- a/gcc/config/i386/i386.md	Thu Oct 15 18:47:39 2009 +0900
+++ b/gcc/config/i386/i386.md	Tue Oct 27 16:04:06 2009 +0900
@@ -15009,6 +15009,18 @@
   DONE;
 })
 
+(define_expand "sibcall_pop"
+  [(parallel [(call (match_operand:QI 0 "" "")
+		    (match_operand:SI 1 "" ""))
+	      (set (reg:SI SP_REG)
+		   (plus:SI (reg:SI SP_REG)
+			    (match_operand:SI 3 "" "")))])]
+  ""
+{
+  ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 1);
+  DONE;
+})
+
 (define_insn "*call_0"
   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
 	 (match_operand 1 "" ""))]
@@ -15132,6 +15144,21 @@
   DONE;
 })
 
+(define_expand "sibcall_value_pop"
+  [(parallel [(set (match_operand 0 "" "")
+		   (call (match_operand:QI 1 "" "")
+			 (match_operand:SI 2 "" "")))
+	      (set (reg:SI SP_REG)
+		   (plus:SI (reg:SI SP_REG)
+			    (match_operand:SI 4 "" "")))])]
+  "!TARGET_64BIT"
+{
+  ix86_expand_call (operands[0], operands[1], operands[2],
+		    operands[3], operands[4], 1);
+  DONE;
+})
+
+
 ;; Call subroutine returning any type.
 
 (define_expand "untyped_call"