summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cg.tgt260
-rw-r--r--cg.wpj10
-rw-r--r--cgcalc.c60
-rw-r--r--cgcode.c96
-rw-r--r--cgcodep.h18
-rw-r--r--cgconst.h30
-rw-r--r--cgias.c177
-rw-r--r--cgiconst.h23
-rw-r--r--cginput.c18
-rw-r--r--cgiwas.c174
-rw-r--r--cglin.c127
-rw-r--r--cgopt.c287
-rw-r--r--cgstack.c34
-rw-r--r--cgtypes.h5
14 files changed, 982 insertions, 337 deletions
diff --git a/cg.tgt b/cg.tgt
index 97afdfc..37d402c 100644
--- a/cg.tgt
+++ b/cg.tgt
@@ -12,7 +12,7 @@ NEXE
3
WString
5
-nc2e9
+nc2en
1
0
0
@@ -32,7 +32,7 @@ WString
NEXE
8
WVList
-11
+9
9
MVState
10
@@ -70,9 +70,9 @@ WINLINK
18
WString
24
-?????Case sensitive link
-1
+?????Produce symbol file
1
+0
19
MCState
20
@@ -82,9 +82,9 @@ WINLINK
21
WString
24
-?????Produce symbol file
+?????Eliminate dead code
+1
1
-0
22
MCState
23
@@ -94,9 +94,9 @@ WINLINK
24
WString
24
-?????Eliminate dead code
-1
-1
+?????Incremental Linking
+0
+0
25
MVState
26
@@ -134,9 +134,9 @@ WINLINK
34
WString
24
-?????Case sensitive link
+?????Produce symbol file
+0
0
-1
35
MCState
36
@@ -146,433 +146,409 @@ WINLINK
37
WString
24
-?????Produce symbol file
-0
-0
-38
-MRState
-39
-WString
-7
-WINLINK
-40
-WString
-19
-nc???Character mode
-0
-1
-41
-MCState
-42
-WString
-7
-WINLINK
-43
-WString
-24
?????Eliminate dead code
0
1
-44
+38
WVList
3
-45
+39
ActionStates
-46
+40
WString
6
&Debug
-47
+41
WVList
0
-48
+42
ActionStates
-49
+43
WString
7
Sam&ple
-50
+44
WVList
0
-51
+45
ActionStates
-52
+46
WString
4
&Run
-53
+47
WVList
0
-1
1
1
0
-54
+48
WPickList
11
-55
+49
MItem
3
*.c
-56
+50
WString
4
COBJ
-57
+51
WVList
13
-58
+52
MVState
-59
+53
WString
3
WCC
-60
+54
WString
23
?????Macro definitions:
1
-61
+55
WString
14
_WINDOWS_ I486
0
-62
+56
MCState
-63
+57
WString
3
WCC
-64
+58
WString
33
?????Disable stack depth checking
0
1
-65
+59
MVState
-66
+60
WString
3
WCC
-67
+61
WString
23
?????Macro definitions:
0
-68
+62
WString
14
_WINDOWS_ I486
0
-69
+63
MRState
-70
+64
WString
3
WCC
-71
+65
WString
20
?????Pack structures
0
0
-72
+66
MRState
-73
+67
WString
3
WCC
-74
+68
WString
21
?????4 byte alignment
0
1
-75
+69
MRState
-76
+70
WString
3
WCC
-77
+71
WString
23
?????Time optimizations
0
1
-78
+72
MRState
-79
+73
WString
3
WCC
-80
+74
WString
26
?????Fastest possible code
0
0
-81
+75
MCState
-82
+76
WString
3
WCC
-83
+77
WString
23
?????Loop optimizations
0
1
-84
+78
MCState
-85
+79
WString
3
WCC
-86
+80
WString
30
?????Call/return optimizations
0
1
-87
+81
MCState
-88
+82
WString
3
WCC
-89
+83
WString
32
?????In-line intrinsic functions
0
1
-90
+84
MCState
-91
+85
WString
3
WCC
-92
+86
WString
27
?????Instruction scheduling
0
1
-93
+87
MVState
-94
+88
WString
3
WCC
-95
+89
WString
29
?????Expand function in-line:
0
-96
+90
WString
2
20
1
-97
+91
MCState
-98
+92
WString
3
WCC
-99
+93
WString
35
?????Put functions in separate segs
0
1
-100
+94
WVList
0
-1
1
1
0
-101
+95
MItem
4
cg.c
-102
+96
WString
4
COBJ
-103
+97
WVList
0
-104
+98
WVList
0
-55
+49
1
1
0
-105
+99
MItem
8
cgcalc.c
-106
+100
WString
4
COBJ
-107
+101
WVList
0
-108
+102
WVList
0
-55
+49
1
1
0
-109
+103
MItem
8
cgcode.c
-110
+104
WString
4
COBJ
-111
+105
WVList
0
-112
+106
WVList
0
-55
+49
1
1
0
-113
+107
MItem
7
cgias.c
-114
+108
WString
4
COBJ
-115
+109
WVList
0
-116
+110
WVList
0
-55
+49
1
1
0
-117
+111
MItem
9
cginput.c
-118
+112
WString
4
COBJ
-119
+113
WVList
0
-120
+114
WVList
0
-55
+49
1
1
0
-121
+115
MItem
16
cginstructions.c
-122
+116
WString
4
COBJ
-123
+117
WVList
0
-124
+118
WVList
0
-55
+49
1
1
0
-125
+119
MItem
8
cgiwas.c
-126
+120
WString
4
COBJ
-127
+121
WVList
0
-128
+122
WVList
0
-55
+49
1
1
0
-129
+123
MItem
7
cglin.c
-130
+124
WString
4
COBJ
-131
+125
WVList
0
-132
+126
WVList
0
-55
+49
1
1
0
-133
+127
MItem
7
cgopt.c
-134
+128
WString
4
COBJ
-135
+129
WVList
0
-136
+130
WVList
0
-55
+49
1
1
0
-137
+131
MItem
9
cgstack.c
-138
+132
WString
4
COBJ
-139
+133
WVList
0
-140
+134
WVList
0
-55
+49
1
1
0
diff --git a/cg.wpj b/cg.wpj
index 7375ef3..eac38c7 100644
--- a/cg.wpj
+++ b/cg.wpj
@@ -4,10 +4,10 @@ projectIdent
VpeMain
1
WRect
-560
-1054
+1475
+1410
7680
-6411
+6400
2
MProject
3
@@ -38,6 +38,6 @@ WRect
WFileName
6
cg.tgt
-1
-1
+0
+9
7
diff --git a/cgcalc.c b/cgcalc.c
index 771457b..73b0504 100644
--- a/cgcalc.c
+++ b/cgcalc.c
@@ -571,7 +571,7 @@ static void calculate_dyadic_non_commutative_data_operator (INSTRUCTION_GRAPH gr
return;
}
-static void calculate_mod_operator (INSTRUCTION_GRAPH graph)
+static void calculate_rem_operator (INSTRUCTION_GRAPH graph)
{
register INSTRUCTION_GRAPH graph_1,graph_2;
int i_aregs,i_dregs;
@@ -2264,8 +2264,10 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph)
calculate_dyadic_commutative_data_operator (graph);
return;
case GCMP_EQ:
- case GCMP_LT:
case GCMP_GT:
+ case GCMP_GTU:
+ case GCMP_LT:
+ case GCMP_LTU:
calculate_compare_operator (graph);
return;
case GSUB:
@@ -2273,10 +2275,16 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph)
calculate_dyadic_non_commutative_operator (graph);
return;
case GDIV:
+#ifdef I486
+ case GDIVU:
+#endif
calculate_dyadic_non_commutative_data_operator (graph);
return;
case GMOD:
- calculate_mod_operator (graph);
+#ifdef I486
+ case GREMU:
+#endif
+ calculate_rem_operator (graph);
return;
case GLSL:
case GLSR:
@@ -2299,6 +2307,10 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph)
calculate_eor_operator (graph);
return;
case GCNOT:
+#ifdef I486
+ case GNEG:
+ case GNOT:
+#endif
calculate_cnot_operator (graph);
return;
case GMOVEMI:
@@ -2330,6 +2342,9 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph)
case GFEXP:
case GFSQRT:
case GFNEG:
+#ifdef I486
+ case GFABS:
+#endif
calculate_monadic_float_operator (graph);
return;
case GFLOAD_ID:
@@ -2468,8 +2483,13 @@ void count_graph (INSTRUCTION_GRAPH graph)
case GAND:
case GCMP_EQ:
case GCMP_GT:
+ case GCMP_GTU:
case GCMP_LT:
+ case GCMP_LTU:
case GDIV:
+#ifdef I486
+ case GDIVU:
+#endif
case GFADD:
case GFCMP_EQ:
case GFCMP_GT:
@@ -2482,6 +2502,9 @@ void count_graph (INSTRUCTION_GRAPH graph)
case GLSL:
case GLSR:
case GMOD:
+#ifdef I486
+ case GREMU:
+#endif
case GMUL:
case GMUL_O:
case GOR:
@@ -2515,6 +2538,11 @@ void count_graph (INSTRUCTION_GRAPH graph)
case GFEXP:
case GFSQRT:
case GFNEG:
+#ifdef I486
+ case GFABS:
+ case GNEG:
+ case GNOT:
+#endif
case GBEFORE0:
case GTEST_O:
if (++graph->node_count==1)
@@ -2620,8 +2648,13 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph)
case GAND:
case GCMP_EQ:
case GCMP_GT:
+ case GCMP_GTU:
case GCMP_LT:
+ case GCMP_LTU:
case GDIV:
+#ifdef I486
+ case GDIVU:
+#endif
case GFADD:
case GFCMP_EQ:
case GFCMP_GT:
@@ -2634,6 +2667,9 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph)
case GLSL:
case GLSR:
case GMOD:
+#ifdef I486
+ case GREMU:
+#endif
case GMUL:
case GMUL_O:
case GOR:
@@ -2668,6 +2704,11 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph)
case GFEXP:
case GFSQRT:
case GFNEG:
+#ifdef I486
+ case GFABS:
+ case GNEG:
+ case GNOT:
+#endif
case GBEFORE0:
case GTEST_O:
if (graph->node_mark<2){
@@ -2787,8 +2828,13 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph)
case GAND:
case GCMP_EQ:
case GCMP_GT:
+ case GCMP_GTU:
case GCMP_LT:
+ case GCMP_LTU:
case GDIV:
+#ifdef I486
+ case GDIVU:
+#endif
case GFADD:
case GFCMP_EQ:
case GFCMP_GT:
@@ -2801,6 +2847,9 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph)
case GLSL:
case GLSR:
case GMOD:
+#ifdef I486
+ case GREMU:
+#endif
case GMUL:
case GMUL_O:
case GOR:
@@ -2833,6 +2882,11 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph)
case GFEXP:
case GFSQRT:
case GFNEG:
+#ifdef I486
+ case GFABS:
+ case GNEG:
+ case GNOT:
+#endif
case GBEFORE0:
case GTEST_O:
if (!graph->node_mark){
diff --git a/cgcode.c b/cgcode.c
index 4e6dd24..80844fc 100644
--- a/cgcode.c
+++ b/cgcode.c
@@ -158,9 +158,18 @@ int no_time_profiling;
#define g_bounds(g1,g2) g_instruction_2(GBOUNDS,(g1),(g2))
#define g_cmp_eq(g1,g2) g_instruction_2(GCMP_EQ,(g1),(g2))
#define g_cmp_gt(g1,g2) g_instruction_2(GCMP_GT,(g1),(g2))
+#ifdef I486
+# define g_cmp_gtu(g1,g2) g_instruction_2(GCMP_GTU,(g1),(g2))
+#endif
#define g_cmp_lt(g1,g2) g_instruction_2(GCMP_LT,(g1),(g2))
+#ifdef I486
+# define g_cmp_ltu(g1,g2) g_instruction_2(GCMP_LTU,(g1),(g2))
+#endif
#define g_cnot(g1) g_instruction_1(GCNOT,(g1))
#define g_div(g1,g2) g_instruction_2(GDIV,(g1),(g2))
+#ifdef I486
+# define g_divu(g1,g2) g_instruction_2(GDIVU,(g1),(g2))
+#endif
#define g_eor(g1,g2) g_instruction_2(GEOR,(g1),(g2))
#define g_fadd(g1,g2) g_instruction_2(GFADD,(g1),(g2))
#define g_fcmp_eq(g1,g2) g_instruction_2(GFCMP_EQ,(g1),(g2))
@@ -179,7 +188,14 @@ int no_time_profiling;
#define g_lsl(g1,g2) g_instruction_2(GLSL,(g1),(g2))
#define g_lsr(g1,g2) g_instruction_2(GLSR,(g1),(g2))
#define g_mod(g1,g2) g_instruction_2(GMOD,(g1),(g2))
+#ifdef I486
+# define g_remu(g1,g2) g_instruction_2(GREMU,(g1),(g2))
+#endif
#define g_mul(g1,g2) g_instruction_2(GMUL,(g1),(g2))
+#ifdef I486
+# define g_neg(g1) g_instruction_1(GNEG,(g1))
+# define g_not(g1) g_instruction_1(GNOT,(g1))
+#endif
#define g_or(g1,g2) g_instruction_2(GOR,(g1),(g2))
#define g_keep(g1,g2) g_instruction_2(GKEEP,(g1),(g2))
#define g_fkeep(g1,g2) g_instruction_2(GFKEEP,(g1),(g2))
@@ -243,7 +259,7 @@ LABEL *eval_fill_label,*eval_upd_labels[33];
static LABEL *print_r_arg_label,*push_t_r_args_label,*push_a_r_args_label;
LABEL *index_error_label;
-#ifdef G_POWER
+#if defined (G_POWER) || defined (I486)
LABEL *r_to_i_buffer_label;
#endif
@@ -435,6 +451,13 @@ static void code_dyadic_sane_operator (LABEL *label)
#endif
}
+#ifdef I486
+void code_absR (void)
+{
+ code_monadic_real_operator (GFABS);
+}
+#endif
+
void code_acosR (VOID)
{
#ifdef M68000
@@ -1770,6 +1793,18 @@ void code_divR (VOID)
#endif
}
+#ifdef I486
+void code_divU (VOID)
+{
+ INSTRUCTION_GRAPH graph_1,graph_2,graph_3;
+
+ graph_1=s_pop_b();
+ graph_2=s_get_b (0);
+ graph_3=g_divu (graph_2,graph_1);
+ s_put_b (0,graph_3);
+}
+#endif
+
void code_entierR (VOID)
{
if (entier_real_label==NULL)
@@ -3237,6 +3272,19 @@ void code_gtR (VOID)
#endif
}
+#ifdef I486
+void code_gtU (VOID)
+{
+ INSTRUCTION_GRAPH graph_1,graph_2,graph_3;
+
+ graph_1=s_pop_b();
+ graph_2=s_get_b (0);
+ graph_3=g_cmp_gtu (graph_2,graph_1);
+
+ s_put_b (0,graph_3);
+}
+#endif
+
void code_halt (VOID)
{
if (halt_label==NULL)
@@ -4021,6 +4069,19 @@ void code_ltR (VOID)
#endif
}
+#ifdef I486
+void code_ltU (VOID)
+{
+ INSTRUCTION_GRAPH graph_1,graph_2,graph_3;
+
+ graph_1=s_pop_b();
+ graph_2=s_get_b (0);
+ graph_3=g_cmp_ltu (graph_2,graph_1);
+
+ s_put_b (0,graph_3);
+}
+#endif
+
void code_remI (VOID)
{
#ifdef M68000
@@ -4052,6 +4113,18 @@ void code_remI (VOID)
#endif
}
+#ifdef I486
+void code_remU (VOID)
+{
+ INSTRUCTION_GRAPH graph_1,graph_2,graph_3;
+
+ graph_1=s_pop_b();
+ graph_2=s_get_b (0);
+ graph_3=g_remu (graph_2,graph_1);
+ s_put_b (0,graph_3);
+}
+#endif
+
static INSTRUCTION_GRAPH multiply_by_constant (unsigned int n,INSTRUCTION_GRAPH graph_1)
{
INSTRUCTION_GRAPH graph_2;
@@ -4264,6 +4337,18 @@ void code_nu (int a_size,int b_size,char *descriptor_name,char *ea_label_name)
last_block->block_ea_label=NULL;
}
+#ifdef I486
+void code_negI (void)
+{
+ INSTRUCTION_GRAPH graph_1,graph_2;
+
+ graph_1=s_get_b (0);
+ graph_2=g_neg (graph_1);
+
+ s_put_b (0,graph_2);
+}
+#endif
+
void code_negR (void)
{
#ifdef M68000
@@ -4296,9 +4381,12 @@ void code_not (VOID)
INSTRUCTION_GRAPH graph_1,graph_2,graph_3;
graph_1=s_get_b (0);
+#ifdef I486
+ graph_3=g_not (graph_1);
+#else
graph_2=g_load_i (-1);
graph_3=g_eor (graph_2,graph_1);
-
+#endif
s_put_b (0,graph_3);
}
@@ -6200,7 +6288,7 @@ void code_RtoI (VOID)
{
INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4;
-#ifdef G_POWER
+#if defined (G_POWER) || defined (I486)
if (r_to_i_buffer_label==NULL)
r_to_i_buffer_label=enter_label ("r_to_i_buffer",IMPORT_LABEL);
@@ -8435,7 +8523,7 @@ void initialize_coding (VOID)
sqrt_real=NULL;
#endif
-#ifdef G_POWER
+#if defined (G_POWER) || defined (I486)
r_to_i_buffer_label=NULL;
#endif
diff --git a/cgcodep.h b/cgcodep.h
index ad18364..a54569e 100644
--- a/cgcodep.h
+++ b/cgcodep.h
@@ -15,6 +15,9 @@
# define ULONG unsigned long
#endif
+#ifdef I486
+void code_absR (void);
+#endif
void code_acosR (VOID);
void code_add_args (int source_offset,int n_arguments,int destination_offset);
void code_addI (VOID);
@@ -62,6 +65,9 @@ void code_decI (VOID);
void code_del_args (int source_offset,int n_arguments,int destination_offset);
void code_divI (VOID);
void code_divR (VOID);
+#ifdef I486
+ void code_divU (VOID);
+#endif
void code_entierR (VOID);
void code_eqB (VOID);
void code_eqB_a (int value,int a_offset);
@@ -112,6 +118,9 @@ void code_get_node_arity (int a_offset);
void code_gtC (VOID);
void code_gtI (VOID);
void code_gtR (VOID);
+#ifdef I486
+void code_gtU (VOID);
+#endif
void code_halt (VOID);
void code_in (char parameters[]);
void code_incI (VOID);
@@ -132,12 +141,21 @@ void code_log10R (VOID);
void code_ltC (VOID);
void code_ltI (VOID);
void code_ltR (VOID);
+#ifdef I486
+void code_ltU (VOID);
+#endif
void code_remI (VOID);
+#ifdef I486
+ void code_remU (VOID);
+#endif
void code_mulI (VOID);
#ifndef M68000
void code_mulIo (VOID);
#endif
void code_mulR (VOID);
+#ifdef I486
+void code_negI (void);
+#endif
void code_negR (VOID);
void code_new_ext_reducer (char descriptor_name[],int a_offset);
void code_new_int_reducer (char label_name[],int a_offset);
diff --git a/cgconst.h b/cgconst.h
index 2553b8c..35644e6 100644
--- a/cgconst.h
+++ b/cgconst.h
@@ -1,22 +1,26 @@
enum {
GADD, GADD_O, GAND, GALLOCATE, GASR, GBEFORE,
- GBEFORE0, GBOUNDS, GCMP_EQ, GCMP_GT, GCMP_LT, GCNOT,
- GCOPY, GCREATE, GCREATE_R, GDIV, GEOR,
- GFACOS, GFADD, GFASIN, GFCMP_EQ, GFCMP_GT, GFATAN,
- GFCMP_LT, GFCOS, GFDIV, GFEXP, GFHIGH, GFITOR,
- GFJOIN, GFKEEP, GFLN, GFLOAD, GFLOAD_I, GFLOAD_ID,
- GFLOAD_X, GFLOG10, GFLOW, GFMOVEMI, GFMUL, GFNEG,
- GFREM, GFRTOI, GFSIN, GFSUB, GFILL, GFILL_R,
- GFREGISTER, GFSQRT, GFSTORE, GFSTORE_R, GFSTORE_X, GFTAN,
- GGFREGISTER, GGREGISTER, GKEEP, GINDIRECTION, GLEA, GLOAD,
- GLOAD_I, GLOAD_ID, GLOAD_X, GLOAD_B_ID, GLOAD_B_X, GLOAD_DES_ID,
- GLOAD_DES_I, GLSL, GLSR, GMOD, GMOVEM, GMOVEMI,
- GMUL, GMUL_O, GOR, GREGISTER, GSTORE, GSTORE_R,
- GSTORE_B_X, GSTORE_X, GSUB, GSUB_O, GTEST_O, GEXIT_IF
+ GBEFORE0, GBOUNDS, GCMP_EQ, GCMP_GT, GCMP_GTU, GCMP_LT,
+ GCMP_LTU, GCNOT, GCOPY, GCREATE, GCREATE_R, GDIV,
+ GEOR, GFACOS, GFADD, GFASIN, GFCMP_EQ, GFCMP_GT,
+ GFATAN, GFCMP_LT, GFCOS, GFDIV, GFEXP, GFHIGH,
+ GFITOR, GFJOIN, GFKEEP, GFLN, GFLOAD, GFLOAD_I,
+ GFLOAD_ID, GFLOAD_X, GFLOG10, GFLOW, GFMOVEMI, GFMUL,
+ GFNEG, GFREM, GFRTOI, GFSIN, GFSUB, GFILL,
+ GFILL_R, GFREGISTER, GFSQRT, GFSTORE, GFSTORE_R, GFSTORE_X,
+ GFTAN, GGFREGISTER, GGREGISTER, GKEEP, GINDIRECTION, GLEA,
+ GLOAD, GLOAD_I, GLOAD_ID, GLOAD_X, GLOAD_B_ID, GLOAD_B_X,
+ GLOAD_DES_ID, GLOAD_DES_I, GLSL, GLSR, GMOD, GMOVEM,
+ GMOVEMI, GMUL, GMUL_O, GOR, GREGISTER, GSTORE,
+ GSTORE_R, GSTORE_B_X, GSTORE_X, GSUB, GSUB_O, GTEST_O,
+ GEXIT_IF
#ifdef G_POWER
,GCREATE_S, GUMULH
#endif
+#ifdef I486
+ ,GDIVU, GREMU, GFABS, GNEG, GNOT
+#endif
};
enum {
diff --git a/cgias.c b/cgias.c
index 760273a..aa0942c 100644
--- a/cgias.c
+++ b/cgias.c
@@ -2149,13 +2149,13 @@ static void as_div_rem_i_instruction (struct instruction *instruction,int comput
}
}
-static void as_div_instruction (struct instruction *instruction)
+static void as_div_instruction (struct instruction *instruction,int unsigned_div)
{
- int d_reg;
+ int d_reg,opcode2;
d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
- if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_div==0){
int i,log2i;
i=instruction->instruction_parameters[0].parameter_data.i;
@@ -2198,24 +2198,28 @@ static void as_div_instruction (struct instruction *instruction)
return;
}
+ opcode2=unsigned_div ? 0060 : 0070;
+
switch (d_reg){
case REGISTER_D0:
as_move_r_r (REGISTER_A1,REGISTER_O0);
- /*cdq*/
- store_c (0231);
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
&& instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
{
- as_r (0367,0070,REGISTER_O0);
+ as_r (0367,opcode2,REGISTER_O0);
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT
&& instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
{
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
} else
- as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
as_move_r_r (REGISTER_O0,REGISTER_A1);
break;
@@ -2223,8 +2227,10 @@ static void as_div_instruction (struct instruction *instruction)
as_move_r_r (REGISTER_D0,REGISTER_O0);
as_move_r_r (REGISTER_A1,REGISTER_D0);
- /*cdq*/
- store_c (0231);
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
@@ -2236,7 +2242,7 @@ static void as_div_instruction (struct instruction *instruction)
else if (r==REGISTER_A1)
r=REGISTER_D0;
- as_r (0367,0070,r);
+ as_r (0367,opcode2,r);
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
int r;
@@ -2246,9 +2252,9 @@ static void as_div_instruction (struct instruction *instruction)
else if (r==REGISTER_A1)
r=REGISTER_D0;
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
} else
- as_parameter (00367,0070,&instruction->instruction_parameters[0]);
+ as_parameter (00367,opcode2,&instruction->instruction_parameters[0]);
as_move_r_r (REGISTER_D0,REGISTER_A1);
as_move_r_r (REGISTER_O0,REGISTER_D0);
@@ -2257,8 +2263,10 @@ static void as_div_instruction (struct instruction *instruction)
as_move_r_r (REGISTER_A1,REGISTER_O0);
store_c (0x90+reg_num (d_reg)); /* xchg d_reg,D0 */
- /*cdq*/
- store_c (0231);
+ if (unsigned_div)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
@@ -2272,7 +2280,7 @@ static void as_div_instruction (struct instruction *instruction)
else if (r==d_reg)
r=REGISTER_D0;
- as_r (0367,0070,r);
+ as_r (0367,opcode2,r);
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
int r;
@@ -2284,7 +2292,7 @@ static void as_div_instruction (struct instruction *instruction)
else if (r==d_reg)
r=REGISTER_D0;
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
} else
as_parameter (0367,0070,&instruction->instruction_parameters[0]);
@@ -2293,13 +2301,13 @@ static void as_div_instruction (struct instruction *instruction)
}
}
-static void as_rem_instruction (struct instruction *instruction)
+static void as_rem_instruction (struct instruction *instruction,int unsigned_rem)
{
- int d_reg;
+ int d_reg,opcode2;
d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
- if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_rem==0){
int i,log2i;
i=instruction->instruction_parameters[0].parameter_data.i;
@@ -2356,24 +2364,28 @@ static void as_rem_instruction (struct instruction *instruction)
return;
}
+ opcode2=unsigned_rem ? 0060 : 0070;
+
switch (d_reg){
case REGISTER_D0:
as_move_r_r (REGISTER_A1,REGISTER_O0);
- /*cdq*/
- store_c (0231);
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
&& instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
{
- as_r (0367,0070,REGISTER_O0);
+ as_r (0367,opcode2,REGISTER_O0);
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT
&& instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
{
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
} else
- as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
as_move_r_r (REGISTER_A1,REGISTER_D0);
as_move_r_r (REGISTER_O0,REGISTER_A1);
@@ -2382,8 +2394,11 @@ static void as_rem_instruction (struct instruction *instruction)
as_move_r_r (REGISTER_D0,REGISTER_O0);
as_move_r_r (REGISTER_A1,REGISTER_D0);
- /*cdq*/
- store_c (0231);
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
+
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -2394,7 +2409,7 @@ static void as_rem_instruction (struct instruction *instruction)
else if (r==REGISTER_A1)
r=REGISTER_D0;
- as_r (0367,0070,r);
+ as_r (0367,opcode2,r);
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
int r;
@@ -2404,9 +2419,9 @@ static void as_rem_instruction (struct instruction *instruction)
else if (r==REGISTER_A1)
r=REGISTER_D0;
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
} else
- as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
as_move_r_r (REGISTER_O0,REGISTER_D0);
break;
@@ -2414,8 +2429,10 @@ static void as_rem_instruction (struct instruction *instruction)
as_move_r_r (REGISTER_A1,REGISTER_O0);
store_c (0x90+reg_num (d_reg)); /* xchg d_reg,D0 */
- /*cdq*/
- store_c (0231);
+ if (unsigned_rem)
+ as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */
+ else
+ store_c (0231); /* cdq */
/* idivl */
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -2428,7 +2445,7 @@ static void as_rem_instruction (struct instruction *instruction)
else if (r==d_reg)
r=REGISTER_D0;
- as_r (0367,0070,r);
+ as_r (0367,opcode2,r);
} else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){
int r;
@@ -2440,9 +2457,9 @@ static void as_rem_instruction (struct instruction *instruction)
else if (r==d_reg)
r=REGISTER_D0;
- as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r);
+ as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r);
} else
- as_parameter (0367,0070,&instruction->instruction_parameters[0]);
+ as_parameter (0367,opcode2,&instruction->instruction_parameters[0]);
as_move_r_r (d_reg,REGISTER_D0);
as_move_r_r (REGISTER_A1,d_reg);
@@ -2600,6 +2617,16 @@ static void as_exg_instruction (struct instruction *instruction)
as_r_r (0207,r1,r2);
}
+static void as_neg_instruction (struct instruction *instruction)
+{
+ as_r (0367,0030,instruction->instruction_parameters[0].parameter_data.reg.r);
+}
+
+static void as_not_instruction (struct instruction *instruction)
+{
+ as_r (0367,0020,instruction->instruction_parameters[0].parameter_data.reg.r);
+}
+
static void as_rtsi_instruction (struct instruction *instruction)
{
store_c (0xc2);
@@ -2685,6 +2712,9 @@ static void as_f_i (int code1,int code2,DOUBLE *r_p)
new_label->label_flags=DATA_LABEL;
+ if (data_object_label==NULL)
+ as_new_data_module();
+
data_object_label->object_section_align8=1;
if ((data_buffer_p-current_data_buffer->data-data_object_label->object_label_offset) & 4)
store_long_word_in_data_section (0);
@@ -2706,7 +2736,7 @@ struct instruction *find_next_fp_instruction (struct instruction *instruction)
while (instruction!=NULL){
switch (instruction->instruction_icode){
case IFADD: case IFSUB: case IFMUL: case IFDIV:
- case IFMOVEL: case IFCMP: case IFNEG: case IFTST: case IFREM:
+ case IFMOVEL: case IFCMP: case IFNEG: case IFABS: case IFTST: case IFREM:
case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE:
case IFSEQ: case IFSGE: case IFSGT: case IFSLE: case IFSLT: case IFSNE:
case IFCOS: case IFSIN: case IFSQRT: case IFTAN:
@@ -2734,7 +2764,7 @@ int next_instruction_is_fld_reg (int reg0,struct instruction *instruction)
if (next_fp_instruction!=NULL){
switch (next_fp_instruction->instruction_icode){
case IFADD: case IFSUB: case IFMUL: case IFDIV:
- case IFSQRT: case IFNEG: case IFSIN: case IFCOS:
+ case IFSQRT: case IFNEG: case IFABS: case IFSIN: case IFCOS:
if (next_fp_instruction->instruction_parameters[0].parameter_type==P_F_REGISTER
&& next_fp_instruction->instruction_parameters[0].parameter_data.reg.r==reg0)
{
@@ -2846,7 +2876,7 @@ static void fstpl_instruction (int reg0,struct instruction *instruction)
return;
} /* else */
- case IFSQRT: case IFNEG: case IFSIN: case IFCOS:
+ case IFSQRT: case IFNEG: case IFABS: case IFSIN: case IFCOS:
if (next_fp_instruction->instruction_parameters[0].parameter_type==P_F_REGISTER
&& next_fp_instruction->instruction_parameters[0].parameter_data.reg.r==reg0)
{
@@ -3651,9 +3681,28 @@ void store_descriptor_string_in_data_section (char *string,int length,LABEL *str
static void as_fmovel_instruction (struct instruction *instruction)
{
- if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER)
- internal_error_in_function ("as_fmovel_instruction");
- else {
+ if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){
+ if (instruction->instruction_parameters[1].parameter_type==P_REGISTER){
+ LABEL *new_label;
+ int s_freg;
+
+ new_label=allocate_memory_from_heap (sizeof (struct label));
+
+ new_label->label_flags=DATA_LABEL;
+
+ define_data_label (new_label);
+ store_long_word_in_data_section (0);
+
+ s_freg=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (s_freg!=0){
+ as_f_r (0xd9,0xc0,s_freg); /* fld s_freg */
+ as_f_a (0xdb,3,new_label); /* fistp */
+ } else
+ as_f_a (0xdb,2,new_label); /* fist */
+ as_r_a (0x8b,instruction->instruction_parameters[1].parameter_data.reg.r,new_label);
+ } else
+ internal_error_in_function ("as_fmovel_instruction");
+ } else {
switch (instruction->instruction_parameters[0].parameter_type){
case P_REGISTER:
{
@@ -3792,21 +3841,30 @@ static void as_instructions (struct instruction *instruction)
case IBGE:
as_branch_instruction (instruction,015);
break;
+ case IBGEU:
+ as_branch_instruction (instruction,003);
+ break;
case IBGT:
as_branch_instruction (instruction,017);
break;
+ case IBGTU:
+ as_branch_instruction (instruction,007);
+ break;
case IBLE:
as_branch_instruction (instruction,016);
break;
+ case IBLEU:
+ as_branch_instruction (instruction,006);
+ break;
case IBLT:
as_branch_instruction (instruction,014);
break;
+ case IBLTU:
+ as_branch_instruction (instruction,002);
+ break;
case IBNE:
as_branch_instruction (instruction,005);
break;
- case IBHS:
- as_branch_instruction (instruction,003);
- break;
case IBO:
as_branch_instruction (instruction,0);
break;
@@ -3826,17 +3884,23 @@ static void as_instructions (struct instruction *instruction)
as_mul_instruction (instruction);
break;
case IDIV:
- as_div_instruction (instruction);
+ as_div_instruction (instruction,0);
break;
case IDIVI:
as_div_rem_i_instruction (instruction,0);
break;
+ case IDIVU:
+ as_div_instruction (instruction,1);
+ break;
case IMOD:
- as_rem_instruction (instruction);
+ as_rem_instruction (instruction,0);
break;
case IREMI:
as_div_rem_i_instruction (instruction,1);
break;
+ case IREMU:
+ as_rem_instruction (instruction,1);
+ break;
case IAND:
as_logic_instruction (instruction,0043,040,045);
break;
@@ -3852,15 +3916,27 @@ static void as_instructions (struct instruction *instruction)
case ISGE:
as_set_condition_instruction (instruction,015);
break;
+ case ISGEU:
+ as_set_condition_instruction (instruction,003);
+ break;
case ISGT:
as_set_condition_instruction (instruction,017);
break;
+ case ISGTU:
+ as_set_condition_instruction (instruction,007);
+ break;
case ISLE:
as_set_condition_instruction (instruction,016);
break;
+ case ISLEU:
+ as_set_condition_instruction (instruction,006);
+ break;
case ISLT:
as_set_condition_instruction (instruction,014);
break;
+ case ISLTU:
+ as_set_condition_instruction (instruction,002);
+ break;
case ISNE:
as_set_condition_instruction (instruction,005);
break;
@@ -3888,6 +3964,12 @@ static void as_instructions (struct instruction *instruction)
case IEXG:
as_exg_instruction (instruction);
break;
+ case INEG:
+ as_neg_instruction (instruction);
+ break;
+ case INOT:
+ as_not_instruction (instruction);
+ break;
case IWORD:
store_c (instruction->instruction_parameters[0].parameter_data.i);
break;
@@ -3946,6 +4028,9 @@ static void as_instructions (struct instruction *instruction)
case IFNEG:
as_monadic_float_instruction (instruction,0xe0);
break;
+ case IFABS:
+ as_monadic_float_instruction (instruction,0xe1);
+ break;
case IFSIN:
as_monadic_float_instruction (instruction,0xfe);
break;
diff --git a/cgiconst.h b/cgiconst.h
index 0c06775..02ca0ac 100644
--- a/cgiconst.h
+++ b/cgiconst.h
@@ -7,16 +7,19 @@
# define FP_STACK_OPTIMIZATIONS
#endif
+#define IBHS IBGEU
+
enum {
- IADD, IAND, IASR, IBEQ, IBGE, IBGT, IBHS,
- IBLE, IBLT, IBNE, IBNO, IBO, ICMP, ICMPW,
- IDIV, IEOR, IEXG, IEXT, IFADD, IFBEQ, IFBGE,
- IFBGT, IFBLE, IFBLT, IFBNE, IFCMP, IFCOS, IFDIV,
- IFMUL, IFNEG, IFREM, IFSEQ, IFSGE, IFSGT, IFSIN,
- IFSLE, IFSLT, IFSNE, IFSUB, IFTAN, IFTST, IFMOVE,
- IFMOVEL, IJMP, IJSR, ILEA, ILSL, ILSR, IMOD,
- IMOVE, IMOVEB, IMOVEW, IMUL, IOR, IRTS, ISCHEDULE,
- ISEQ, ISGE, ISGT, ISLE, ISLT, ISNE, ISNO,
+ IADD, IAND, IASR, IBEQ, IBGE, IBGEU, IBGT,
+ IBGTU, IBLE, IBLEU, IBLT, IBLTU, IBNE, IBNO,
+ IBO, ICMP, ICMPW, IDIV, IEOR, IEXG, IEXT,
+ IFADD, IFBEQ, IFBGE, IFBGT, IFBLE, IFBLT, IFBNE,
+ IFCMP, IFCOS, IFDIV, IFMUL, IFNEG, IFREM, IFSEQ,
+ IFSGE, IFSGT, IFSIN, IFSLE, IFSLT, IFSNE, IFSUB,
+ IFTAN, IFTST, IFMOVE, IFMOVEL, IJMP, IJSR, ILEA,
+ ILSL, ILSR, IMOD, IMOVE, IMOVEB, IMOVEW, IMUL,
+ IOR, IRTS, ISCHEDULE, ISEQ, ISGE, ISGEU, ISGT,
+ ISGTU, ISLE, ISLEU, ISLT, ISLTU, ISNE, ISNO,
ISO, ISUB, ITST, IWORD
#if !defined (G_POWER)
,IFSQRT
@@ -52,7 +55,7 @@ enum {
,IFEXG
#endif
#if defined (I486)
- ,IRTSI, IDIVI, IREMI
+ ,IRTSI, IDIVI, IREMI, IDIVU, IREMU, IFABS, INEG, INOT
#endif
#ifdef G_POWER
,IUMULH
diff --git a/cginput.c b/cginput.c
index ee6bab6..d26a8bf 100644
--- a/cginput.c
+++ b/cginput.c
@@ -1717,6 +1717,9 @@ static void put_instruction_name
static void put_instructions_in_table (void)
{
+#ifdef I486
+ put_instruction_name ("absR", parse_instruction, code_absR );
+#endif
put_instruction_name ("acosR", parse_instruction, code_acosR );
put_instruction_name ("add_args", parse_instruction_n_n_n, code_add_args );
put_instruction_name ("addI", parse_instruction, code_addI );
@@ -1760,6 +1763,9 @@ static void put_instructions_in_table (void)
put_instruction_name ("del_args", parse_instruction_n_n_n, code_del_args );
put_instruction_name ("divI", parse_instruction, code_divI );
put_instruction_name ("divR", parse_instruction, code_divR );
+#ifdef I486
+ put_instruction_name ("divU", parse_instruction, code_divU );
+#endif
put_instruction_name ("entierR", parse_instruction, code_entierR );
put_instruction_name ("eqB", parse_instruction, code_eqB );
put_instruction_name ("eqB_a", parse_instruction_b_n, code_eqB_a );
@@ -1810,6 +1816,9 @@ static void put_instructions_in_table (void)
put_instruction_name ("gtC", parse_instruction, code_gtC );
put_instruction_name ("gtI", parse_instruction, code_gtI );
put_instruction_name ("gtR", parse_instruction, code_gtR );
+#ifdef I486
+ put_instruction_name ("gtU", parse_instruction, code_gtU );
+#endif
put_instruction_name ("halt", parse_instruction, code_halt );
put_instruction_name ("in", parse_instruction_in_or_out, code_in );
put_instruction_name ("incI", parse_instruction, code_incI );
@@ -1834,9 +1843,15 @@ static void put_instructions_in_table (void)
put_instruction_name ("ltC", parse_instruction, code_ltC );
put_instruction_name ("ltI", parse_instruction, code_ltI );
put_instruction_name ("ltR", parse_instruction, code_ltR );
+#ifdef I486
+ put_instruction_name ("ltU", parse_instruction, code_ltU );
+#endif
put_instruction_name ("modI", parse_instruction, code_remI );
put_instruction_name ("mulI", parse_instruction, code_mulI );
put_instruction_name ("mulR", parse_instruction, code_mulR );
+#ifdef I486
+ put_instruction_name ("negI", parse_instruction, code_negI );
+#endif
put_instruction_name ("negR", parse_instruction, code_negR );
put_instruction_name ("new_ext_reducer",parse_instruction_a_n, code_new_ext_reducer );
put_instruction_name ("new_int_reducer",parse_instruction_a_n, code_new_int_reducer );
@@ -1911,6 +1926,9 @@ static void put_instructions_in_table2 (void)
put_instruction_name ("randomP", parse_instruction, code_randomP );
put_instruction_name ("release", parse_instruction, code_release );
put_instruction_name ("remI", parse_instruction, code_remI );
+#ifdef I486
+ put_instruction_name ("remU", parse_instruction, code_remU );
+#endif
put_instruction_name ("replace", parse_instruction_a_n_n, code_replace );
put_instruction_name ("repl_arg", parse_instruction_n_n, code_repl_arg );
put_instruction_name ("repl_args", parse_instruction_n_n, code_repl_args );
diff --git a/cgiwas.c b/cgiwas.c
index a31d06e..4064d9c 100644
--- a/cgiwas.c
+++ b/cgiwas.c
@@ -1270,6 +1270,13 @@ static void w_as_tst_instruction (struct instruction *instruction,int size_flag)
}
}
+static void w_as_monadic_instruction (struct instruction *instruction,char *opcode)
+{
+ w_as_opcode (opcode);
+ w_as_register (instruction->instruction_parameters[0].parameter_data.reg.r);
+ w_as_newline();
+}
+
static void w_as_btst_instruction (struct instruction *instruction)
{
if (instruction->instruction_parameters[1].parameter_type==P_REGISTER){
@@ -1378,7 +1385,7 @@ static void as_test_floating_point_condition_code (int n)
fprintf (assembly_file,intel_asm ? "\tand\tah,69\n\tdec\tah\n\tcmp\tah,64\n" : "\tandb\t$69,%%ah\n\tdecb\t%%ah\n\tcmpb\t$64,%%ah\n");
break;
case 5:
- fprintf (assembly_file,intel_asm ? "\tand\tah,5\n" : "\tand\t5,%%ah\n");
+ fprintf (assembly_file,intel_asm ? "\tand\tah,5\n" : "\tand\t$5,%%ah\n");
break;
}
}
@@ -1687,7 +1694,7 @@ static void w_as_div_rem_i_instruction (struct instruction *instruction,int comp
}
}
-static void w_as_div_instruction (struct instruction *instruction)
+static void w_as_div_instruction (struct instruction *instruction,int unsigned_div)
{
int d_reg;
@@ -1697,8 +1704,8 @@ static void w_as_div_instruction (struct instruction *instruction)
int i,log2i;
i=instruction->instruction_parameters[0].parameter_data.i;
-
- if ((i & (i-1))==0 && i>0){
+
+ if (unsigned_div==0 && (i & (i-1))==0 && i>0){
if (i==1)
return;
@@ -1729,19 +1736,24 @@ static void w_as_div_instruction (struct instruction *instruction)
w_as_immediate_register_newline (log2i,d_reg);
return;
- } else {
- internal_error_in_function ("w_as_div_instruction");
- return;
}
+
+ internal_error_in_function ("w_as_div_instruction");
+ return;
}
switch (d_reg){
case REGISTER_D0:
w_as_movl_register_register_newline (REGISTER_A1,REGISTER_O0);
-
- w_as_instruction_without_parameters ("cdq");
-
- w_as_opcode (intel_asm ? "idiv" : "idivl");
+
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
+
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
&& instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
{
@@ -1765,9 +1777,13 @@ static void w_as_div_instruction (struct instruction *instruction)
w_as_movl_register_register_newline (REGISTER_A1,REGISTER_D0);
- w_as_instruction_without_parameters ("cdq");
-
- w_as_opcode (intel_asm ? "idiv" : "idivl");
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -1805,9 +1821,13 @@ static void w_as_div_instruction (struct instruction *instruction)
w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg);
- w_as_instruction_without_parameters ("cdq");
-
- w_as_opcode (intel_asm ? "idiv" : "idivl");
+ if (unsigned_div){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -1846,13 +1866,13 @@ static void w_as_div_instruction (struct instruction *instruction)
}
}
-static void w_as_rem_instruction (struct instruction *instruction)
+static void w_as_rem_instruction (struct instruction *instruction,int unsigned_rem)
{
int d_reg;
d_reg=instruction->instruction_parameters[1].parameter_data.reg.r;
- if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_rem==0){
int i,log2i;
i=instruction->instruction_parameters[0].parameter_data.i;
@@ -1903,9 +1923,14 @@ static void w_as_rem_instruction (struct instruction *instruction)
case REGISTER_D0:
w_as_movl_register_register_newline (REGISTER_A1,REGISTER_O0);
- w_as_instruction_without_parameters ("cdq");
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
- w_as_opcode ("idivl");
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER
&& instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1)
{
@@ -1932,9 +1957,13 @@ static void w_as_rem_instruction (struct instruction *instruction)
w_as_movl_register_register_newline (REGISTER_A1,REGISTER_D0);
- w_as_instruction_without_parameters ("cdq");
-
- w_as_opcode ("idivl");
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -1970,9 +1999,13 @@ static void w_as_rem_instruction (struct instruction *instruction)
w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg);
- w_as_instruction_without_parameters ("cdq");
-
- w_as_opcode (intel_asm ? "idiv" : "idivl");
+ if (unsigned_rem){
+ w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1);
+ w_as_opcode (intel_asm ? "div" : "divl");
+ } else {
+ w_as_instruction_without_parameters ("cdq");
+ w_as_opcode (intel_asm ? "idiv" : "idivl");
+ }
if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){
int r;
@@ -2174,7 +2207,7 @@ static void fstpl_instruction (int reg0,struct instruction *instruction)
return;
} /* else */
- case IFSQRT: case IFNEG: case IFSIN: case IFCOS:
+ case IFSQRT: case IFNEG: case IFABS: case IFSIN: case IFCOS:
if (next_fp_instruction->instruction_parameters[0].parameter_type==P_F_REGISTER
&& next_fp_instruction->instruction_parameters[0].parameter_data.reg.r==reg0)
{
@@ -2691,9 +2724,42 @@ static int int_to_real_scratch_imported=0;
static void w_as_fmovel_instruction (struct instruction *instruction)
{
- if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER)
- internal_error_in_function ("w_as_fmovel_instruction");
- else {
+ if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){
+ if (instruction->instruction_parameters[1].parameter_type==P_REGISTER){
+ int s_freg;
+
+ if (intel_asm && !int_to_real_scratch_imported){
+ w_as_opcode ("extrn");
+ fprintf (assembly_file,"%s:near\n","int_to_real_scratch");
+ int_to_real_scratch_imported=1;
+ }
+
+ s_freg=instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (s_freg!=0){
+ w_as_opcode ("fld");
+ w_as_fp_register (s_freg);
+ w_as_newline();
+
+ w_as_opcode (!intel_asm ? "fistpl" : "fistp");
+ } else
+ w_as_opcode (!intel_asm ? "fistl" : "fist");
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+ w_as_label ("int_to_real_scratch");
+ w_as_newline();
+
+ w_as_opcode_movl();
+ if (intel_asm){
+ w_as_register_comma (instruction->instruction_parameters[1].parameter_data.reg.r);
+ fprintf (assembly_file,"dword ptr ");
+ }
+ w_as_label ("int_to_real_scratch");
+ if (!intel_asm)
+ w_as_comma_register (instruction->instruction_parameters[1].parameter_data.reg.r);
+ w_as_newline();
+ } else
+ internal_error_in_function ("w_as_fmovel_instruction");
+ } else {
switch (instruction->instruction_parameters[0].parameter_type){
case P_REGISTER:
if (intel_asm && !int_to_real_scratch_imported){
@@ -2877,21 +2943,30 @@ static void w_as_instructions (register struct instruction *instruction)
case IBGE:
w_as_branch_instruction (instruction,"jge");
break;
+ case IBGEU:
+ w_as_branch_instruction (instruction,"jae");
+ break;
case IBGT:
w_as_branch_instruction (instruction,"jg");
break;
+ case IBGTU:
+ w_as_branch_instruction (instruction,"ja");
+ break;
case IBLE:
w_as_branch_instruction (instruction,"jle");
break;
+ case IBLEU:
+ w_as_branch_instruction (instruction,"jbe");
+ break;
case IBLT:
w_as_branch_instruction (instruction,"jl");
break;
+ case IBLTU:
+ w_as_branch_instruction (instruction,"jb");
+ break;
case IBNE:
w_as_branch_instruction (instruction,"jne");
break;
- case IBHS:
- w_as_branch_instruction (instruction,"jae");
- break;
case IBO:
w_as_branch_instruction (instruction,"jo");
break;
@@ -2911,17 +2986,23 @@ static void w_as_instructions (register struct instruction *instruction)
w_as_dyadic_instruction (instruction,intel_asm ? "imul" : "imull");
break;
case IDIV:
- w_as_div_instruction (instruction);
+ w_as_div_instruction (instruction,0);
break;
case IDIVI:
w_as_div_rem_i_instruction (instruction,0);
break;
+ case IDIVU:
+ w_as_div_instruction (instruction,1);
+ break;
case IMOD:
- w_as_rem_instruction (instruction);
+ w_as_rem_instruction (instruction,0);
break;
case IREMI:
w_as_div_rem_i_instruction (instruction,1);
break;
+ case IREMU:
+ w_as_rem_instruction (instruction,1);
+ break;
case IAND:
w_as_dyadic_instruction (instruction,intel_asm ? "and" : "andl");
break;
@@ -2937,15 +3018,27 @@ static void w_as_instructions (register struct instruction *instruction)
case ISGE:
w_as_set_condition_instruction (instruction,"setge");
break;
+ case ISGEU:
+ w_as_set_condition_instruction (instruction,"setae");
+ break;
case ISGT:
w_as_set_condition_instruction (instruction,"setg");
break;
+ case ISGTU:
+ w_as_set_condition_instruction (instruction,"seta");
+ break;
case ISLE:
w_as_set_condition_instruction (instruction,"setle");
break;
+ case ISLEU:
+ w_as_set_condition_instruction (instruction,"setbe");
+ break;
case ISLT:
w_as_set_condition_instruction (instruction,"setl");
break;
+ case ISLTU:
+ w_as_set_condition_instruction (instruction,"setb");
+ break;
case ISNE:
w_as_set_condition_instruction (instruction,"setne");
break;
@@ -2973,6 +3066,12 @@ static void w_as_instructions (register struct instruction *instruction)
case IEXG:
w_as_dyadic_instruction (instruction,"xchg");
break;
+ case INEG:
+ w_as_monadic_instruction (instruction,intel_asm ? "neg" : "negl");
+ break;
+ case INOT:
+ w_as_monadic_instruction (instruction,intel_asm ? "not" : "notl");
+ break;
case IFMOVE:
instruction=w_as_fmove_instruction (instruction);
break;
@@ -3028,6 +3127,9 @@ static void w_as_instructions (register struct instruction *instruction)
case IFNEG:
w_as_monadic_float_instruction (instruction,"fchs");
break;
+ case IFABS:
+ w_as_monadic_float_instruction (instruction,"fabs");
+ break;
case IFSIN:
w_as_monadic_float_instruction (instruction,"fsin");
break;
diff --git a/cglin.c b/cglin.c
index b9b9f32..b293c9a 100644
--- a/cglin.c
+++ b/cglin.c
@@ -3068,7 +3068,8 @@ static int compare_node (INSTRUCTION_GRAPH graph,int i_test_1,int i_test_2)
}
enum {
- CEQ, CNE, CGT, CLT, CGE, CLE, CO, CNO,
+ CEQ, CNE, CGT, CLT, CGE, CLE,
+ CO, CNO, CGTU, CLTU, CGEU, CLEU,
CFEQ, CFNE, CFGT, CFLT, CFGE, CFLE
};
@@ -3076,19 +3077,22 @@ enum {
int condition_to_set_instruction[]=
{
- ISEQ, ISNE, ISGT, ISLT, ISGE, ISLE, ISO, ISNO,
+ ISEQ, ISNE, ISGT, ISLT, ISGE, ISLE,
+ ISO, ISNO, ISGTU, ISLTU, ISGEU, ISLEU,
IFSEQ, IFSNE, IFSGT, IFSLT, IFSGE, IFSLE
};
static int condition_to_branch_false_instruction[]=
{
- IBNE, IBEQ, IBLE, IBGE, IBLT, IBGT, IBNO, IBO,
+ IBNE, IBEQ, IBLE, IBGE, IBLT, IBGT,
+ IBNO, IBO, IBLEU, IBGEU, IBLTU, IBGTU,
IFBNE, IFBEQ, IFBLE, IFBGE, IFBLT, IFBGT
};
static int condition_to_branch_true_instruction[]=
{
- IBEQ, IBNE, IBGT, IBLT, IBGE, IBLE, IBO, IBNO,
+ IBEQ, IBNE, IBGT, IBLT, IBGE, IBLE,
+ IBO, IBNO, IBGTU, IBLTU, IBGEU, IBLEU,
IFBEQ, IFBNE, IFBGT, IFBLT, IFBGE, IFBLE
};
@@ -3125,9 +3129,15 @@ static int linearize_condition (INSTRUCTION_GRAPH graph)
case GCMP_LT:
condition=compare_node (graph,CLT,CGT);
break;
+ case GCMP_LTU:
+ condition=compare_node (graph,CLTU,CGTU);
+ break;
case GCMP_GT:
condition=compare_node (graph,CGT,CLT);
break;
+ case GCMP_GTU:
+ condition=compare_node (graph,CGTU,CLTU);
+ break;
case GFCMP_EQ:
condition=float_compare_node (graph,CFEQ,CFEQ);
break;
@@ -3186,9 +3196,15 @@ static int linearize_not_condition (INSTRUCTION_GRAPH graph)
case GCMP_LT:
condition=compare_node (graph,CGE,CLE);
break;
+ case GCMP_LTU:
+ condition=compare_node (graph,CGEU,CLEU);
+ break;
case GCMP_GT:
condition=compare_node (graph,CLE,CGE);
break;
+ case GCMP_GTU:
+ condition=compare_node (graph,CLEU,CGEU);
+ break;
case GFCMP_EQ:
condition=float_compare_node (graph,CFNE,CFNE);
break;
@@ -3364,8 +3380,41 @@ static void linearize_dyadic_non_commutative_data_operator (int i_instruction_co
register_node (graph,reg_1);
}
+#ifdef I486
+static void linearize_monadic_data_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
+{
+ INSTRUCTION_GRAPH graph_1;
+ ADDRESS ad_1;
+ int reg_1;
+
+ graph_1=graph->instruction_parameters[0].p;
+
+ linearize_graph (graph_1,&ad_1);
+
+ in_alterable_data_register (&ad_1);
+ reg_1=ad_1.ad_register;
+ instruction_r (i_instruction_code,reg_1);
+
+ if (graph->instruction_d_min_a_cost>0){
+ int areg;
+
+ areg=get_aregister();
+ i_move_r_r (reg_1,areg);
+ free_dregister (reg_1);
+ reg_1=areg;
+ }
+
+ ad_p->ad_mode=P_REGISTER;
+ ad_p->ad_register=reg_1;
+
+ ad_p->ad_count_p=&graph->node_count;
+ if (*ad_p->ad_count_p>1)
+ register_node (graph,reg_1);
+}
+#endif
+
#if defined (I486) || defined (G_POWER)
-static void linearize_div_mod_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
+static void linearize_div_rem_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
{
INSTRUCTION_GRAPH graph_1,graph_2;
ADDRESS ad_1,ad_2;
@@ -3387,23 +3436,28 @@ static void linearize_div_mod_operator (int i_instruction_code,INSTRUCTION_GRAPH
# ifdef I486
if (ad_1.ad_mode==P_IMMEDIATE){
- int i;
-
- i=ad_1.ad_offset;
- if (i_instruction_code==IMOD && i<0 && i!=0x80000000)
- i=-i;
-
- if ((i & (i-1))==0 && (i_instruction_code==IMOD ? i>1 : i>0))
- instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
- else if (i>1 || (i<-1 && i!=0x80000000)){
- int tmp_reg;
-
- tmp_reg=get_dregister();
- instruction_ad_r_r (i_instruction_code==IDIV ? IDIVI : IREMI,&ad_1,ad_2.ad_register,tmp_reg);
- free_dregister (tmp_reg);
- } else {
+ if (i_instruction_code==IDIVU || i_instruction_code==IREMU){
in_data_register (&ad_1);
- instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+ instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+ } else {
+ int i;
+
+ i=ad_1.ad_offset;
+ if (i_instruction_code==IMOD && i<0 && i!=0x80000000)
+ i=-i;
+
+ if ((i & (i-1))==0 && (i_instruction_code==IMOD ? i>1 : i>0))
+ instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+ else if (i>1 || (i<-1 && i!=0x80000000)){
+ int tmp_reg;
+
+ tmp_reg=get_dregister();
+ instruction_ad_r_r (i_instruction_code==IDIV ? IDIVI : IREMI,&ad_1,ad_2.ad_register,tmp_reg);
+ free_dregister (tmp_reg);
+ } else {
+ in_data_register (&ad_1);
+ instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+ }
}
} else {
if (ad_1.ad_mode==P_INDEXED)
@@ -6053,6 +6107,11 @@ static void linearize_float_graph (register INSTRUCTION_GRAPH graph,register ADD
case GFNEG:
linearize_monadic_float_operator (graph,ad_p,IFNEG);
break;
+#ifdef I486
+ case GFABS:
+ linearize_monadic_float_operator (graph,ad_p,IFABS);
+ break;
+#endif
case GFSIN:
linearize_monadic_float_operator (graph,ad_p,IFSIN);
break;
@@ -7512,11 +7571,19 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
return;
#if defined (I486) || defined (G_POWER)
case GDIV:
- linearize_div_mod_operator (IDIV,graph,ad_p);
+ linearize_div_rem_operator (IDIV,graph,ad_p);
return;
case GMOD:
- linearize_div_mod_operator (IMOD,graph,ad_p);
+ linearize_div_rem_operator (IMOD,graph,ad_p);
+ return;
+# ifdef I486
+ case GDIVU:
+ linearize_div_rem_operator (IDIVU,graph,ad_p);
+ return;
+ case GREMU:
+ linearize_div_rem_operator (IREMU,graph,ad_p);
return;
+# endif
#else
case GDIV:
linearize_dyadic_non_commutative_data_operator (IDIV,graph,ad_p);
@@ -7531,9 +7598,15 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
case GCMP_LT:
linearize_compare_operator (CLT,CGT,graph,ad_p);
return;
+ case GCMP_LTU:
+ linearize_compare_operator (CLTU,CGTU,graph,ad_p);
+ return;
case GCMP_GT:
linearize_compare_operator (CGT,CLT,graph,ad_p);
return;
+ case GCMP_GTU:
+ linearize_compare_operator (CGTU,CLTU,graph,ad_p);
+ return;
case GCNOT:
linearize_conditional_not_operator (graph,ad_p);
return;
@@ -7564,6 +7637,14 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
case GFILL_R:
linearize_fill_r_operator (graph,ad_p);
return;
+#ifdef I486
+ case GNEG:
+ linearize_monadic_data_operator (INEG,graph,ad_p);
+ return;
+ case GNOT:
+ linearize_monadic_data_operator (INOT,graph,ad_p);
+ return;
+#endif
case GMOVEMI:
linearize_movemi_operator (graph,ad_p);
return;
diff --git a/cgopt.c b/cgopt.c
index f9dee23..292258e 100644
--- a/cgopt.c
+++ b/cgopt.c
@@ -40,9 +40,10 @@
# define IF_G_RISC(a)
#endif
-#define POWER_PC_A_STACK_OPTIMIZE
+#define for_l(v,l,n) for(v=(l);v!=NULL;v=v->n)
-#define for_all(v,l,n) for(v=(l);v!=NULL;v=v->n)
+#define POWER_PC_A_STACK_OPTIMIZE
+#undef OPTIMIZE_LOOPS
#pragma segment Code4
@@ -50,12 +51,14 @@
extern struct basic_block *first_block;
-static void optimize_branch_jump
- (struct instruction *branch,struct instruction *jump,struct basic_block *jump_block)
+#ifdef OPTIMIZE_LOOPS
+extern LABEL *new_local_label (int label_flags);
+#endif
+
+static void optimize_branch_jump (struct instruction *branch,LABEL *new_branch_label)
{
- branch->instruction_parameters[0].parameter_data.l=
- jump->instruction_parameters[0].parameter_data.l;
-
+ branch->instruction_parameters[0].parameter_data.l=new_branch_label;
+
switch (branch->instruction_icode){
case IBEQ: branch->instruction_icode=IBNE; break;
case IBGE: branch->instruction_icode=IBLT; break;
@@ -63,6 +66,10 @@ static void optimize_branch_jump
case IBLE: branch->instruction_icode=IBGT; break;
case IBLT: branch->instruction_icode=IBGE; break;
case IBNE: branch->instruction_icode=IBEQ; break;
+ case IBGEU: branch->instruction_icode=IBLTU; break;
+ case IBGTU: branch->instruction_icode=IBLEU; break;
+ case IBLEU: branch->instruction_icode=IBGTU; break;
+ case IBLTU: branch->instruction_icode=IBGEU; break;
case IFBEQ: branch->instruction_icode=IFBNE; break;
case IFBGE: branch->instruction_icode=IFBLT; break;
case IFBGT: branch->instruction_icode=IFBLE; break;
@@ -70,20 +77,41 @@ static void optimize_branch_jump
case IFBLT: branch->instruction_icode=IFBGE; break;
case IFBNE: branch->instruction_icode=IFBEQ;
}
-
- jump_block->block_instructions=NULL;
}
-void optimize_jumps()
+#ifdef OPTIMIZE_LOOPS
+static LABEL *get_label_of_block (struct basic_block *block)
+{
+ if (block->block_labels!=NULL)
+ return block->block_labels->block_label_label;
+ else {
+ struct block_label *new_block_label;
+ LABEL *new_jmp_label;
+
+ new_jmp_label=new_local_label (0);
+
+ new_block_label=fast_memory_allocate_type (struct block_label);
+ new_block_label->block_label_label=new_jmp_label;
+ new_block_label->block_label_next=NULL;
+
+ block->block_labels=new_block_label;
+
+ return new_jmp_label;
+ }
+}
+#endif
+
+void optimize_jumps (void)
{
struct basic_block *block;
- for_all (block,first_block,block_next){
+ for_l (block,first_block,block_next){
struct instruction *branch;
if ((branch=block->block_last_instruction)!=NULL){
switch (branch->instruction_icode){
- case IBEQ: case IBGE: case IBGT: case IBLE: case IBLT: case IBNE:
+ case IBEQ: case IBGE: case IBGT: case IBLE: case IBLT:
+ case IBNE: case IBGEU: case IBGTU: case IBLEU: case IBLTU:
case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE:
{
struct basic_block *next_block;
@@ -110,25 +138,54 @@ void optimize_jumps()
#endif
)
{
- for ( block_labels=next_next_block->block_labels;
- block_labels!=NULL;
- block_labels=block_labels->block_label_next
- )
+ for_l (block_labels,next_next_block->block_labels,block_label_next)
if (block_labels->block_label_label==branch_label){
- optimize_branch_jump (branch,jump,next_block);
+ optimize_branch_jump (branch,jump->instruction_parameters[0].parameter_data.l);
+ next_block->block_instructions=NULL;
+#ifdef OPTIMIZE_LOOPS
+ next_block->block_last_instruction=NULL;
+#endif
break;
}
}
}
}
}
+
+#ifdef OPTIMIZE_LOOPS
+ {
+ struct instruction *cmp_instruction;
+
+ cmp_instruction=block->block_instructions;
+ if (cmp_instruction->instruction_icode==ICMP && cmp_instruction->instruction_next==branch
+ && (cmp_instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE ||
+ cmp_instruction->instruction_parameters[0].parameter_type==P_REGISTER ||
+ (cmp_instruction->instruction_parameters[0].parameter_type==P_INDIRECT &&
+ cmp_instruction->instruction_parameters[1].parameter_type==P_REGISTER))
+ && (cmp_instruction->instruction_parameters[1].parameter_type==P_REGISTER ||
+ cmp_instruction->instruction_parameters[1].parameter_type==P_INDIRECT)
+ ){
+ struct block_label *block_label;
+
+ for_l (block_label,block->block_labels,block_label_next){
+ LABEL *label;
+
+ label=block_label->block_label_label;
+ label->label_flags |= CMP_BRANCH_BLOCK_LABEL;
+ label->label_block = block;
+ }
+ }
+ }
+#endif
break;
}
case IJMP:
{
struct basic_block *next_block;
-
- if ((next_block=block->block_next)!=NULL){
+
+ if (branch->instruction_parameters[0].parameter_type==P_LABEL
+ && (next_block=block->block_next)!=NULL)
+ {
struct block_label *labels;
LABEL *jmp_label;
@@ -144,7 +201,14 @@ void optimize_jumps()
if (branch->instruction_prev!=NULL)
branch->instruction_prev->instruction_next=NULL;
else
+#ifdef OPTIMIZE_LOOPS
+ {
+ block->block_instructions=NULL;
+ block->block_last_instruction=NULL;
+ }
+#else
block->block_instructions=NULL;
+#endif
break;
}
}
@@ -187,6 +251,140 @@ void optimize_jumps()
}
}
}
+
+#ifdef OPTIMIZE_LOOPS
+ for_l (block,first_block,block_next){
+ struct instruction *branch;
+
+ if ((branch=block->block_last_instruction)!=NULL &&
+ branch->instruction_icode==IJMP && branch->instruction_parameters[0].parameter_type==P_LABEL)
+ {
+ LABEL *jmp_label;
+
+ jmp_label=branch->instruction_parameters[0].parameter_data.l;
+ if (jmp_label->label_flags & CMP_BRANCH_BLOCK_LABEL){
+ struct basic_block *jmp_block,*jmp_next_block;
+ struct block_label *branch_block_label,*branch_next_block_label;
+ struct instruction *old_cmp_instruction,*old_branch_instruction,*new_branch_instruction;
+ LABEL *branch_label,*new_jmp_label;
+# ifdef I486
+ struct instruction *previous_instruction;
+# endif
+
+ jmp_block=jmp_label->label_block;
+ old_cmp_instruction=jmp_block->block_instructions;
+ jmp_next_block=jmp_block->block_next;
+ old_branch_instruction=old_cmp_instruction->instruction_next;
+
+ branch_label=old_branch_instruction->instruction_parameters[0].parameter_data.l;
+
+ branch_next_block_label=NULL;
+ if (block->block_next!=NULL)
+ for_l (branch_next_block_label,block->block_next->block_labels,block_label_next)
+ if (branch_next_block_label->block_label_label==branch_label)
+ break;
+
+ branch_block_label=NULL;
+ if (branch_next_block_label==NULL)
+ for_l (branch_block_label,block->block_labels,block_label_next)
+ if (branch_block_label->block_label_label==branch_label)
+ break;
+
+# ifdef I486
+ if (old_cmp_instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE &&
+ old_cmp_instruction->instruction_parameters[0].parameter_data.i==0 &&
+ old_cmp_instruction->instruction_parameters[1].parameter_type==P_REGISTER &&
+ (previous_instruction=branch->instruction_prev)!=NULL &&
+ (previous_instruction->instruction_icode==ISUB || previous_instruction->instruction_icode==IADD) &&
+ previous_instruction->instruction_parameters[1].parameter_type==P_REGISTER &&
+ old_cmp_instruction->instruction_parameters[1].parameter_data.reg.r==previous_instruction->instruction_parameters[1].parameter_data.reg.r)
+ {
+ new_jmp_label = get_label_of_block (jmp_next_block);
+
+ if (branch_next_block_label!=NULL){
+ branch->instruction_icode=old_branch_instruction->instruction_icode;
+ branch->instruction_parameters[0]=old_branch_instruction->instruction_parameters[0];
+
+ optimize_branch_jump (branch,new_jmp_label);
+ } else {
+ new_branch_instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+sizeof (struct parameter));
+
+ new_branch_instruction->instruction_icode=old_branch_instruction->instruction_icode;
+ new_branch_instruction->instruction_arity=1;
+ new_branch_instruction->instruction_parameters[0]=old_branch_instruction->instruction_parameters[0];
+
+ if (block->block_instructions==branch){
+ block->block_instructions=new_branch_instruction;
+ new_branch_instruction->instruction_prev=NULL;
+ } else {
+ struct instruction *previous_instruction;
+
+ previous_instruction=branch->instruction_prev;
+ previous_instruction->instruction_next=new_branch_instruction;
+ new_branch_instruction->instruction_prev=previous_instruction;
+ }
+ new_branch_instruction->instruction_next=branch;
+
+ branch->instruction_prev=new_branch_instruction;
+
+ branch->instruction_parameters[0].parameter_data.l=new_jmp_label;
+ }
+ } else
+# endif
+
+ if (branch_next_block_label!=NULL || branch_block_label!=NULL){
+ struct instruction *new_cmp_instruction;
+
+ new_cmp_instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter));
+
+ new_cmp_instruction->instruction_icode=ICMP;
+ new_cmp_instruction->instruction_arity=2;
+ new_cmp_instruction->instruction_parameters[0]=old_cmp_instruction->instruction_parameters[0];
+ new_cmp_instruction->instruction_parameters[1]=old_cmp_instruction->instruction_parameters[1];
+
+ if (block->block_instructions==branch){
+ block->block_instructions=new_cmp_instruction;
+ new_cmp_instruction->instruction_prev=NULL;
+ } else {
+ struct instruction *previous_instruction;
+
+ previous_instruction=branch->instruction_prev;
+ previous_instruction->instruction_next=new_cmp_instruction;
+ new_cmp_instruction->instruction_prev=previous_instruction;
+ }
+
+ new_jmp_label = get_label_of_block (jmp_next_block);
+
+ if (branch_next_block_label!=NULL){
+ branch->instruction_icode=old_branch_instruction->instruction_icode;
+ branch->instruction_parameters[0]=old_branch_instruction->instruction_parameters[0];
+
+ optimize_branch_jump (branch,new_jmp_label);
+
+ new_cmp_instruction->instruction_next=branch;
+
+ branch->instruction_prev=new_cmp_instruction;
+ } else {
+ new_branch_instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+sizeof (struct parameter));
+
+ new_branch_instruction->instruction_icode=old_branch_instruction->instruction_icode;
+ new_branch_instruction->instruction_arity=1;
+ new_branch_instruction->instruction_parameters[0]=old_branch_instruction->instruction_parameters[0];
+
+ new_cmp_instruction->instruction_next=new_branch_instruction;
+
+ new_branch_instruction->instruction_prev=new_cmp_instruction;
+ new_branch_instruction->instruction_next=branch;
+
+ branch->instruction_prev=new_branch_instruction;
+
+ branch->instruction_parameters[0].parameter_data.l=new_jmp_label;
+ }
+ }
+ }
+ }
+ }
+#endif
}
#if defined (M68000) || defined (I486)
@@ -209,7 +407,7 @@ static int get_argument_size (int instruction_code)
IF_G_RISC (case IADDI: case ILSLI:)
IF_G_SPARC (case IADDO: case ISUBO: )
#ifdef I486
- case IDIVI: case REMI:
+ case IDIVI: case IREMI: case IDIVU: case IREMU:
#endif
IF_G_POWER ( case IUMULH: )
return 4;
@@ -221,6 +419,9 @@ IF_G_POWER ( case IUMULH: )
#if !defined (G_POWER)
case IFSQRT:
#endif
+#ifdef I486
+ case IFABS:
+#endif
return 8;
default:
return 0;
@@ -449,7 +650,7 @@ static void compute_maximum_b_stack_offsets (register int b_offset)
{
struct instruction *instruction;
- for_all (instruction,last_instruction,instruction_prev){
+ for_l (instruction,last_instruction,instruction_prev){
switch (instruction->instruction_arity){
default:
if (
@@ -459,6 +660,7 @@ static void compute_maximum_b_stack_offsets (register int b_offset)
#ifdef I486
instruction->instruction_icode!=IDIVI &&
instruction->instruction_icode!=IREMI &&
+ instruction->instruction_icode!=IREMU &&
#endif
instruction->instruction_icode!=IMOD)
#ifdef M68000
@@ -511,7 +713,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off
compute_maximum_b_stack_offsets (*b_offset_p);
# ifdef M68000
- for_all (instruction,block->block_instructions,instruction_next){
+ for_l (instruction,block->block_instructions,instruction_next){
switch (instruction->instruction_arity){
default:
if (
@@ -594,7 +796,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off
# endif
# ifdef I486
- for_all (instruction,block->block_instructions,instruction_next){
+ for_l (instruction,block->block_instructions,instruction_next){
if (instruction->instruction_icode==IMOVE){
if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT &&
instruction->instruction_parameters[0].parameter_data.reg.r==B_STACK_POINTER)
@@ -692,6 +894,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off
default:
if (instruction->instruction_icode!=IDIVI &&
instruction->instruction_icode!=IREMI &&
+ instruction->instruction_icode!=IREMU &&
instruction->instruction_icode!=IMOD)
internal_error_in_function ("optimize_stack_access");
/* only first argument of mod might be register indirect */
@@ -722,7 +925,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off
# endif
# ifdef OLDI486
- for_all (instruction,block->block_instructions,instruction_next){
+ for_l (instruction,block->block_instructions,instruction_next){
if (instruction->instruction_icode==IMOVE){
if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT &&
instruction->instruction_parameters[0].parameter_data.reg.r==B_STACK_POINTER &&
@@ -799,8 +1002,8 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off
if (a_offset==0)
return;
-
- for_all (instruction,block->block_instructions,instruction_next){
+
+ for_l (instruction,block->block_instructions,instruction_next){
if (instruction->instruction_icode==IMOVE){
if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT &&
instruction->instruction_parameters[0].parameter_data.reg.r==A_STACK_POINTER &&
@@ -1302,6 +1505,9 @@ static void store_next_uses (struct instruction *instruction)
#ifndef I486_USE_SCRATCH_REGISTER
case IASR: case ILSL: case ILSR:
case IDIV:
+# ifdef I486
+ case IDIVU:
+# endif
case ICMPW:
#endif
case IEOR: case IFADD:
@@ -1331,7 +1537,7 @@ IF_G_POWER ( case IUMULH: )
use_parameter (&instruction->instruction_parameters[1]);
use_parameter (&instruction->instruction_parameters[0]);
break;
- case IDIV: case IMOD:
+ case IDIV: case IMOD: case IDIVU: case IREMU:
define_scratch_register();
use_parameter (&instruction->instruction_parameters[1]);
use_parameter (&instruction->instruction_parameters[0]);
@@ -1368,6 +1574,9 @@ IF_G_POWER ( case IUMULH: )
#if !defined (G_POWER)
case IFSQRT:
#endif
+#ifdef I486
+ case IFABS:
+#endif
IF_G_SPARC (case IFMOVEHI: case IFMOVELO:)
IF_G_RISC (case IADDI: case ILSLI:)
define_parameter (&instruction->instruction_parameters[1]);
@@ -1382,7 +1591,7 @@ IF_G_RISC (case IADDI: case ILSLI:)
break;
case IFSEQ: case IFSGE: case IFSGT: case IFSLE: case IFSLT: case IFSNE:
case ISEQ: case ISGE: case ISGT: case ISLE: case ISLT: case ISNE:
- case ISO: case ISNO:
+ case ISO: case ISGEU: case ISGTU: case ISLEU: case ISLTU: case ISNO:
#ifdef I486_USE_SCRATCH_REGISTER
define_scratch_register();
#endif
@@ -1392,6 +1601,9 @@ IF_G_RISC (case IADDI: case ILSLI:)
case IMOD:
# if defined (I486) || defined (G_POWER)
use_parameter (&instruction->instruction_parameters[1]);
+# ifdef I486
+ case IREMU:
+# endif
use_parameter (&instruction->instruction_parameters[0]);
break;
# else
@@ -1429,8 +1641,7 @@ IF_G_RISC (case IADDI: case ILSLI:)
break;
*/
case IBEQ: case IBGE: case IBGT: case IBLE: case IBLT: case IBNE:
- case IBHS:
- case IBO: case IBNO:
+ case IBO: case IBGEU: case IBGTU: case IBLEU: case IBLTU: case IBNO:
break;
default:
internal_error_in_function ("store_next_uses");
@@ -3578,6 +3789,9 @@ static void allocate_registers (struct basic_block *basic_block)
#ifndef I486_USE_SCRATCH_REGISTER
case IASR: case ILSL: case ILSR:
case IDIV:
+# ifdef I486
+ case IDIVU:
+# endif
#endif
case IEOR:
case IFADD: case IFCMP: case IFDIV: case IFMUL: case IFREM: case IFSUB:
@@ -3593,7 +3807,7 @@ IF_G_POWER ( case IUMULH: )
instruction_use_2 (instruction,USE_DEF);
allocate_scratch_register=1;
break;
- case IDIV: case IMOD:
+ case IDIV: case IMOD: case IDIVU: case IREMU:
use_scratch_register();
instruction_use_2 (instruction,USE_DEF);
allocate_scratch_register=1;
@@ -3643,6 +3857,9 @@ IF_G_POWER (case ICMPLW:)
#if !defined (G_POWER)
case IFSQRT:
#endif
+#ifdef I486
+ case IFABS:
+#endif
IF_G_SPARC (case IFMOVEHI: case IFMOVELO:)
IF_G_RISC (case IADDI: case ILSLI:)
@@ -3675,7 +3892,7 @@ IF_G_RISC (case IADDI: case ILSLI:)
break;
}
case ISEQ: case ISGE: case ISGT: case ISLE: case ISLT: case ISNE:
- case ISO: case ISNO:
+ case ISO: case ISGEU: case ISGTU: case ISLEU: case ISLTU: case ISNO:
#ifdef I486_USE_SCRATCH_REGISTER
use_scratch_register();
#endif
@@ -3697,6 +3914,9 @@ IF_G_RISC (case IADDI: case ILSLI:)
#ifndef I486_USE_SCRATCH_REGISTER
case IMOD:
# if defined (I486) || defined (G_POWER)
+# ifdef I486
+ case IREMU:
+# endif
instruction_use_2 (instruction,USE_DEF);
# else
instruction_mod_use_def_use (instruction);
@@ -3736,8 +3956,7 @@ IF_G_RISC (case IADDI: case ILSLI:)
break;
*/
case IBEQ: case IBGE: case IBGT: case IBLE: case IBLT: case IBNE:
- case IBO: case IBNO:
- case IBHS:
+ case IBO: case IBGEU: case IBGTU: case IBLEU: case IBLTU: case IBNO:
break;
default:
internal_error_in_function ("allocate_registers");
diff --git a/cgstack.c b/cgstack.c
index 73163e5..d5284d4 100644
--- a/cgstack.c
+++ b/cgstack.c
@@ -3194,7 +3194,7 @@ int block_stack_displacement;
static WORD *check_size_p;
#endif
-static int stack_access_and_adjust_a_stack_pointer (int extra_b_offset)
+static int stack_access_and_adjust_a_stack_pointer (int extra_b_offset,int do_not_alter_condition_codes)
{
int a_offset,b_offset,minimum_b_offset;
@@ -3270,32 +3270,34 @@ static int stack_access_and_adjust_a_stack_pointer (int extra_b_offset)
if (a_offset!=0)
#ifdef I486
- i_lea_id_r (a_offset,A_STACK_POINTER,A_STACK_POINTER);
-#else
+ if (do_not_alter_condition_codes)
+ i_lea_id_r (a_offset,A_STACK_POINTER,A_STACK_POINTER);
+ else
+#endif
if (a_offset>0)
i_add_i_r (a_offset,A_STACK_POINTER);
else
i_sub_i_r (-a_offset,A_STACK_POINTER);
-#endif
return b_offset;
}
-static void stack_access (void)
+static void stack_access (int do_not_alter_condition_codes)
{
register int b_offset;
- b_offset=stack_access_and_adjust_a_stack_pointer (0);
+ b_offset=stack_access_and_adjust_a_stack_pointer (0,do_not_alter_condition_codes);
if (b_offset!=0)
#ifdef I486
- i_lea_id_r (b_offset,B_STACK_POINTER,B_STACK_POINTER);
-#else
+ if (do_not_alter_condition_codes)
+ i_lea_id_r (b_offset,B_STACK_POINTER,B_STACK_POINTER);
+ else
+#endif
if (b_offset>0)
i_add_i_r (b_offset,B_STACK_POINTER);
else
i_sub_i_r (-b_offset,B_STACK_POINTER);
-#endif
}
static int local_register_allocation_and_adjust_a_stack_pointer (int extra_b_offset)
@@ -3304,7 +3306,7 @@ static int local_register_allocation_and_adjust_a_stack_pointer (int extra_b_off
get_n_virtual_registers (&n_virtual_a_regs,&n_virtual_d_regs,&n_virtual_f_regs);
do_register_allocation (last_instruction,last_block,n_virtual_a_regs,n_virtual_d_regs,n_virtual_f_regs,0,0);
- return stack_access_and_adjust_a_stack_pointer (extra_b_offset);
+ return stack_access_and_adjust_a_stack_pointer (extra_b_offset,0);
}
void adjust_stack_pointers (void)
@@ -3313,7 +3315,7 @@ void adjust_stack_pointers (void)
get_n_virtual_registers (&n_virtual_a_regs,&n_virtual_d_regs,&n_virtual_f_regs);
do_register_allocation (last_instruction,last_block,n_virtual_a_regs,n_virtual_d_regs,n_virtual_f_regs,0,0);
- stack_access();
+ stack_access (0);
}
int adjust_stack_pointers_without_altering_condition_codes (int float_condition,int condition)
@@ -3322,7 +3324,7 @@ int adjust_stack_pointers_without_altering_condition_codes (int float_condition,
get_n_virtual_registers (&n_virtual_a_regs,&n_virtual_d_regs,&n_virtual_f_regs);
condition_on_stack=do_register_allocation (last_instruction,last_block,n_virtual_a_regs,n_virtual_d_regs,n_virtual_f_regs,1+float_condition,condition);
- stack_access();
+ stack_access (1);
return condition_on_stack;
}
@@ -3755,14 +3757,10 @@ static void generate_code_for_basic_block (struct block_graph *next_block_graph)
}
#else
if (b_offset!=0)
-# ifdef I486
- i_lea_id_r (b_offset,B_STACK_POINTER,B_STACK_POINTER);
-# else
if (b_offset<0)
i_sub_i_r (-b_offset,B_STACK_POINTER);
else
i_add_i_r (b_offset,B_STACK_POINTER);
-# endif
# if ! defined (sparc)
{
@@ -4187,14 +4185,10 @@ void end_basic_block_with_registers (int n_a_parameters,int n_b_parameters,ULONG
b_offset=end_basic_block_with_registers_and_return_b_stack_offset (n_a_parameters,n_b_parameters,vector,N_ADDRESS_PARAMETER_REGISTERS);
if (b_offset!=0)
-#ifdef I486
- i_lea_id_r (b_offset,B_STACK_POINTER,B_STACK_POINTER);
-#else
if (b_offset>0)
i_add_i_r (b_offset,B_STACK_POINTER);
else
i_sub_i_r (-b_offset,B_STACK_POINTER);
-#endif
}
void end_stack_elements (int n_a_parameters,int n_b_parameters,ULONG vector[])
diff --git a/cgtypes.h b/cgtypes.h
index 927330f..50f2229 100644
--- a/cgtypes.h
+++ b/cgtypes.h
@@ -36,6 +36,7 @@ typedef struct label {
} label_u1;
union {
struct basic_block * u_last_lea_block; /* cgcode.c */
+ struct basic_block * u_block; /* cgopt.c */
#ifdef G_POWER
struct toc_label * u_toc_labels; /* cgpwas.c */
#endif
@@ -43,7 +44,8 @@ typedef struct label {
WORD label_last_lea_arity;
} LABEL;
-#define label_last_lea_block label_u2.u_last_lea_block
+#define label_last_lea_block label_u2.u_last_lea_block
+#define label_block label_u2.u_block
#ifdef G_POWER
# define label_toc_labels label_u2.u_toc_labels
#endif
@@ -66,6 +68,7 @@ typedef struct label {
# define DOT_O_BEFORE_LABEL 2048
# define STUB_GENERATED 4096
#endif
+#define CMP_BRANCH_BLOCK_LABEL 8192
struct label_node {
struct label_node * label_node_left;