Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
225b8835
Commit
225b8835
authored
Mar 27, 1995
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for mult instruction in 64 bit mode
From-SVN: r9234
parent
b6da8566
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
106 additions
and
30 deletions
+106
-30
gcc/config/mips/mips.c
+76
-14
gcc/config/mips/mips.h
+30
-16
gcc/config/mips/mips.md
+0
-0
No files found.
gcc/config/mips/mips.c
View file @
225b8835
...
@@ -246,7 +246,7 @@ char mips_reg_names[][8] =
...
@@ -246,7 +246,7 @@ char mips_reg_names[][8] =
"$f8"
,
"$f9"
,
"$f10"
,
"$f11"
,
"$f12"
,
"$f13"
,
"$f14"
,
"$f15"
,
"$f8"
,
"$f9"
,
"$f10"
,
"$f11"
,
"$f12"
,
"$f13"
,
"$f14"
,
"$f15"
,
"$f16"
,
"$f17"
,
"$f18"
,
"$f19"
,
"$f20"
,
"$f21"
,
"$f22"
,
"$f23"
,
"$f16"
,
"$f17"
,
"$f18"
,
"$f19"
,
"$f20"
,
"$f21"
,
"$f22"
,
"$f23"
,
"$f24"
,
"$f25"
,
"$f26"
,
"$f27"
,
"$f28"
,
"$f29"
,
"$f30"
,
"$f31"
,
"$f24"
,
"$f25"
,
"$f26"
,
"$f27"
,
"$f28"
,
"$f29"
,
"$f30"
,
"$f31"
,
"hi"
,
"lo"
,
"$fcr31"
"hi"
,
"lo"
,
"
accum"
,
"
$fcr31"
};
};
/* Mips software names for the registers, used to overwrite the
/* Mips software names for the registers, used to overwrite the
...
@@ -262,7 +262,7 @@ char mips_sw_reg_names[][8] =
...
@@ -262,7 +262,7 @@ char mips_sw_reg_names[][8] =
"$f8"
,
"$f9"
,
"$f10"
,
"$f11"
,
"$f12"
,
"$f13"
,
"$f14"
,
"$f15"
,
"$f8"
,
"$f9"
,
"$f10"
,
"$f11"
,
"$f12"
,
"$f13"
,
"$f14"
,
"$f15"
,
"$f16"
,
"$f17"
,
"$f18"
,
"$f19"
,
"$f20"
,
"$f21"
,
"$f22"
,
"$f23"
,
"$f16"
,
"$f17"
,
"$f18"
,
"$f19"
,
"$f20"
,
"$f21"
,
"$f22"
,
"$f23"
,
"$f24"
,
"$f25"
,
"$f26"
,
"$f27"
,
"$f28"
,
"$f29"
,
"$f30"
,
"$f31"
,
"$f24"
,
"$f25"
,
"$f26"
,
"$f27"
,
"$f28"
,
"$f29"
,
"$f30"
,
"$f31"
,
"hi"
,
"lo"
,
"$fcr31"
"hi"
,
"lo"
,
"
accum"
,
"
$fcr31"
};
};
/* Map hard register number to register class */
/* Map hard register number to register class */
...
@@ -284,7 +284,7 @@ enum reg_class mips_regno_to_class[] =
...
@@ -284,7 +284,7 @@ enum reg_class mips_regno_to_class[] =
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
FP_REGS
,
HI_REG
,
LO_REG
,
ST_REGS
HI_REG
,
LO_REG
,
HILO_REG
,
ST_REGS
};
};
/* Map register constraint character to register class. */
/* Map register constraint character to register class. */
...
@@ -927,7 +927,10 @@ mips_move_1word (operands, insn, unsignedp)
...
@@ -927,7 +927,10 @@ mips_move_1word (operands, insn, unsignedp)
else
if
(
MD_REG_P
(
regno1
))
else
if
(
MD_REG_P
(
regno1
))
{
{
delay
=
DELAY_HILO
;
delay
=
DELAY_HILO
;
ret
=
"mf%1
\t
%0"
;
if
(
regno1
!=
HILO_REGNUM
)
ret
=
"mf%1
\t
%0"
;
else
ret
=
"mflo
\t
%0"
;
}
}
else
else
...
@@ -958,7 +961,8 @@ mips_move_1word (operands, insn, unsignedp)
...
@@ -958,7 +961,8 @@ mips_move_1word (operands, insn, unsignedp)
if
(
GP_REG_P
(
regno1
))
if
(
GP_REG_P
(
regno1
))
{
{
delay
=
DELAY_HILO
;
delay
=
DELAY_HILO
;
ret
=
"mt%0
\t
%1"
;
if
(
regno0
!=
HILO_REGNUM
)
ret
=
"mt%0
\t
%1"
;
}
}
}
}
...
@@ -1040,6 +1044,12 @@ mips_move_1word (operands, insn, unsignedp)
...
@@ -1040,6 +1044,12 @@ mips_move_1word (operands, insn, unsignedp)
delay
=
DELAY_LOAD
;
delay
=
DELAY_LOAD
;
ret
=
"mtc1
\t
%z1,%0"
;
ret
=
"mtc1
\t
%z1,%0"
;
}
}
else
if
(
MD_REG_P
(
regno0
))
{
delay
=
DELAY_HILO
;
ret
=
"mt%0
\t
%."
;
}
}
}
else
if
(
GP_REG_P
(
regno0
))
else
if
(
GP_REG_P
(
regno0
))
...
@@ -1301,7 +1311,12 @@ mips_move_2words (operands, insn)
...
@@ -1301,7 +1311,12 @@ mips_move_2words (operands, insn)
{
{
delay
=
DELAY_HILO
;
delay
=
DELAY_HILO
;
if
(
TARGET_64BIT
)
if
(
TARGET_64BIT
)
ret
=
"mt%0
\t
%1"
;
{
if
(
regno0
!=
HILO_REGNUM
)
ret
=
"mt%0
\t
%1"
;
else
if
(
regno1
==
0
)
ret
=
"mtlo
\t
%.
\n\t
mthi
\t
%."
;
}
else
else
ret
=
"mthi
\t
%M1
\n\t
mtlo
\t
%L1"
;
ret
=
"mthi
\t
%M1
\n\t
mtlo
\t
%L1"
;
}
}
...
@@ -1310,7 +1325,10 @@ mips_move_2words (operands, insn)
...
@@ -1310,7 +1325,10 @@ mips_move_2words (operands, insn)
{
{
delay
=
DELAY_HILO
;
delay
=
DELAY_HILO
;
if
(
TARGET_64BIT
)
if
(
TARGET_64BIT
)
ret
=
"mf%1
\t
%0"
;
{
if
(
regno1
!=
HILO_REGNUM
)
ret
=
"mf%1
\t
%0"
;
}
else
else
ret
=
"mfhi
\t
%M0
\n\t
mflo
\t
%L0"
;
ret
=
"mfhi
\t
%M0
\n\t
mflo
\t
%L0"
;
}
}
...
@@ -1398,6 +1416,14 @@ mips_move_2words (operands, insn)
...
@@ -1398,6 +1416,14 @@ mips_move_2words (operands, insn)
?
"li.d
\t
%0,%1"
?
"li.d
\t
%0,%1"
:
"mtc1
\t
%.,%0
\n\t
mtc1
\t
%.,%D0"
);
:
"mtc1
\t
%.,%0
\n\t
mtc1
\t
%.,%D0"
);
}
}
else
if
(
MD_REG_P
(
regno0
))
{
delay
=
DELAY_HILO
;
if
(
regno0
!=
HILO_REGNUM
)
ret
=
"mt%0
\t
%.
\n
"
;
else
ret
=
"mtlo
\t
%.
\n\t
mthi
\t
%."
;
}
}
}
else
if
(
code1
==
CONST_INT
&&
GET_MODE
(
op0
)
==
DImode
&&
GP_REG_P
(
regno0
))
else
if
(
code1
==
CONST_INT
&&
GET_MODE
(
op0
)
==
DImode
&&
GP_REG_P
(
regno0
))
...
@@ -3352,7 +3378,9 @@ override_options ()
...
@@ -3352,7 +3378,9 @@ override_options ()
mips_char_to_class
[
'f'
]
=
((
TARGET_HARD_FLOAT
)
?
FP_REGS
:
NO_REGS
);
mips_char_to_class
[
'f'
]
=
((
TARGET_HARD_FLOAT
)
?
FP_REGS
:
NO_REGS
);
mips_char_to_class
[
'h'
]
=
HI_REG
;
mips_char_to_class
[
'h'
]
=
HI_REG
;
mips_char_to_class
[
'l'
]
=
LO_REG
;
mips_char_to_class
[
'l'
]
=
LO_REG
;
mips_char_to_class
[
'a'
]
=
HILO_REG
;
mips_char_to_class
[
'x'
]
=
MD_REGS
;
mips_char_to_class
[
'x'
]
=
MD_REGS
;
mips_char_to_class
[
'b'
]
=
ALL_REGS
;
mips_char_to_class
[
'y'
]
=
GR_REGS
;
mips_char_to_class
[
'y'
]
=
GR_REGS
;
mips_char_to_class
[
'z'
]
=
ST_REGS
;
mips_char_to_class
[
'z'
]
=
ST_REGS
;
...
@@ -5533,24 +5561,58 @@ mips_function_value (valtype, func)
...
@@ -5533,24 +5561,58 @@ mips_function_value (valtype, func)
}
}
#endif
#endif
/* Moving the HI or LO register somewhere requires a general register. */
/* This function returns the register class required for a secondary
register when copying between one of the registers in CLASS, and X,
using MODE. If IN_P is nonzero, the copy is going from X to the
register, otherwise the register is the source. A return value of
NO_REGS means that no secondary register is required. */
enum
reg_class
enum
reg_class
mips_secondary_reload_class
(
class
,
mode
,
x
)
mips_secondary_reload_class
(
class
,
mode
,
x
,
in_p
)
enum
reg_class
class
;
enum
reg_class
class
;
enum
machine_mode
mode
;
enum
machine_mode
mode
;
rtx
x
;
rtx
x
;
int
in_p
;
{
{
if
(
class
!=
HI_REG
&&
class
!=
LO_REG
&&
class
!=
MD_REGS
)
int
regno
=
-
1
;
return
NO_REGS
;
if
(
GET_CODE
(
x
)
==
REG
||
GET_CODE
(
x
)
==
SUBREG
)
if
(
GET_CODE
(
x
)
==
REG
||
GET_CODE
(
x
)
==
SUBREG
)
regno
=
true_regnum
(
x
);
/* We always require a general register when copying anything to
HILO_REGNUM, except when copying an SImode value from HILO_REGNUM
to a general register, or when copying from register 0. */
if
(
class
==
HILO_REG
&&
regno
!=
GP_REG_FIRST
+
0
)
{
if
(
!
in_p
&&
GP_REG_P
(
regno
)
&&
GET_MODE_SIZE
(
mode
)
<=
GET_MODE_SIZE
(
SImode
))
return
NO_REGS
;
return
GR_REGS
;
}
if
(
regno
==
HILO_REGNUM
)
{
{
int
regno
=
true_regnum
(
x
);
if
(
in_p
&&
class
==
GR_REGS
&&
GET_MODE_SIZE
(
mode
)
<=
GET_MODE_SIZE
(
SImode
))
return
NO_REGS
;
return
GR_REGS
;
}
if
(
regno
>=
GP_REG_FIRST
&&
regno
<=
GP_REG_LAST
)
/* Copying from HI or LO to anywhere other than a general register
requires a general register. */
if
(
class
==
HI_REG
||
class
==
LO_REG
||
class
==
MD_REGS
)
{
if
(
GP_REG_P
(
regno
))
return
NO_REGS
;
return
GR_REGS
;
}
if
(
MD_REG_P
(
regno
))
{
if
(
class
==
GR_REGS
)
return
NO_REGS
;
return
NO_REGS
;
return
GR_REGS
;
}
}
return
GR
_REGS
;
return
NO
_REGS
;
}
}
gcc/config/mips/mips.h
View file @
225b8835
...
@@ -1138,10 +1138,13 @@ do { \
...
@@ -1138,10 +1138,13 @@ do { \
All registers that the compiler knows about must be given numbers,
All registers that the compiler knows about must be given numbers,
even those that are not normally considered general registers.
even those that are not normally considered general registers.
On the Mips, we have 32 integer registers, 32 floating point registers
On the Mips, we have 32 integer registers, 32 floating point
and the special registers hi, lo, and fp status. */
registers and the special registers hi, lo, hilo, and fp status.
The hilo register is only used in 64 bit mode. It represents a 64
bit value stored as two 32 bit values in the hi and lo registers;
this is the result of the mult instruction. */
#define FIRST_PSEUDO_REGISTER 6
7
#define FIRST_PSEUDO_REGISTER 6
8
/* 1 for registers that have pervasive standard uses
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
and are not available for the register allocator.
...
@@ -1154,7 +1157,7 @@ do { \
...
@@ -1154,7 +1157,7 @@ do { \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 1 \
0, 0,
0,
1 \
}
}
...
@@ -1171,7 +1174,7 @@ do { \
...
@@ -1171,7 +1174,7 @@ do { \
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, \
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
1, 1, 1 \
1, 1, 1
, 1
\
}
}
...
@@ -1190,16 +1193,17 @@ do { \
...
@@ -1190,16 +1193,17 @@ do { \
#define FP_DBX_FIRST ((write_symbols == DBX_DEBUG) ? 38 : 32)
#define FP_DBX_FIRST ((write_symbols == DBX_DEBUG) ? 38 : 32)
#define MD_REG_FIRST 64
#define MD_REG_FIRST 64
#define MD_REG_LAST 6
5
#define MD_REG_LAST 6
6
#define MD_REG_NUM (MD_REG_LAST - MD_REG_FIRST + 1)
#define MD_REG_NUM (MD_REG_LAST - MD_REG_FIRST + 1)
#define ST_REG_FIRST 6
6
#define ST_REG_FIRST 6
7
#define ST_REG_LAST 6
6
#define ST_REG_LAST 6
7
#define ST_REG_NUM (ST_REG_LAST - ST_REG_FIRST + 1)
#define ST_REG_NUM (ST_REG_LAST - ST_REG_FIRST + 1)
#define AT_REGNUM (GP_REG_FIRST + 1)
#define AT_REGNUM (GP_REG_FIRST + 1)
#define HI_REGNUM (MD_REG_FIRST + 0)
#define HI_REGNUM (MD_REG_FIRST + 0)
#define LO_REGNUM (MD_REG_FIRST + 1)
#define LO_REGNUM (MD_REG_FIRST + 1)
#define HILO_REGNUM (MD_REG_FIRST + 2)
#define FPSW_REGNUM ST_REG_FIRST
#define FPSW_REGNUM ST_REG_FIRST
#define GP_REG_P(REGNO) ((unsigned) ((REGNO) - GP_REG_FIRST) < GP_REG_NUM)
#define GP_REG_P(REGNO) ((unsigned) ((REGNO) - GP_REG_FIRST) < GP_REG_NUM)
...
@@ -1342,6 +1346,7 @@ enum reg_class
...
@@ -1342,6 +1346,7 @@ enum reg_class
FP_REGS
,
/* floating point registers */
FP_REGS
,
/* floating point registers */
HI_REG
,
/* hi register */
HI_REG
,
/* hi register */
LO_REG
,
/* lo register */
LO_REG
,
/* lo register */
HILO_REG
,
/* hilo register pair for 64 bit mode mult */
MD_REGS
,
/* multiply/divide registers (hi/lo) */
MD_REGS
,
/* multiply/divide registers (hi/lo) */
ST_REGS
,
/* status registers (fp status) */
ST_REGS
,
/* status registers (fp status) */
ALL_REGS
,
/* all registers */
ALL_REGS
,
/* all registers */
...
@@ -1363,6 +1368,7 @@ enum reg_class
...
@@ -1363,6 +1368,7 @@ enum reg_class
"FP_REGS", \
"FP_REGS", \
"HI_REG", \
"HI_REG", \
"LO_REG", \
"LO_REG", \
"HILO_REG", \
"MD_REGS", \
"MD_REGS", \
"ST_REGS", \
"ST_REGS", \
"ALL_REGS" \
"ALL_REGS" \
...
@@ -1386,9 +1392,10 @@ enum reg_class
...
@@ -1386,9 +1392,10 @@ enum reg_class
{ 0x00000000, 0xffffffff, 0x00000000 },
/* floating registers*/
\
{ 0x00000000, 0xffffffff, 0x00000000 },
/* floating registers*/
\
{ 0x00000000, 0x00000000, 0x00000001 },
/* hi register */
\
{ 0x00000000, 0x00000000, 0x00000001 },
/* hi register */
\
{ 0x00000000, 0x00000000, 0x00000002 },
/* lo register */
\
{ 0x00000000, 0x00000000, 0x00000002 },
/* lo register */
\
{ 0x00000000, 0x00000000, 0x00000004 },
/* hilo register */
\
{ 0x00000000, 0x00000000, 0x00000003 },
/* mul/div registers */
\
{ 0x00000000, 0x00000000, 0x00000003 },
/* mul/div registers */
\
{ 0x00000000, 0x00000000, 0x0000000
4
},
/* status registers */
\
{ 0x00000000, 0x00000000, 0x0000000
8
},
/* status registers */
\
{ 0xffffffff, 0xffffffff, 0x0000000
7
}
/* all registers */
\
{ 0xffffffff, 0xffffffff, 0x0000000
f
}
/* all registers */
\
}
}
...
@@ -1428,7 +1435,9 @@ extern enum reg_class mips_regno_to_class[];
...
@@ -1428,7 +1435,9 @@ extern enum reg_class mips_regno_to_class[];
'h' Hi register
'h' Hi register
'l' Lo register
'l' Lo register
'x' Multiply/divide registers
'x' Multiply/divide registers
'z' FP Status register */
'a' HILO_REG
'z' FP Status register
'b' All registers */
extern
enum
reg_class
mips_char_to_class
[];
extern
enum
reg_class
mips_char_to_class
[];
...
@@ -1548,8 +1557,10 @@ extern enum reg_class mips_char_to_class[];
...
@@ -1548,8 +1557,10 @@ extern enum reg_class mips_char_to_class[];
/* The HI and LO registers can only be reloaded via the general
/* The HI and LO registers can only be reloaded via the general
registers. */
registers. */
#define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
mips_secondary_reload_class (CLASS, MODE, X)
mips_secondary_reload_class (CLASS, MODE, X, 1)
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
mips_secondary_reload_class (CLASS, MODE, X, 0)
/* Not declared above, with the other functions, because enum
/* Not declared above, with the other functions, because enum
reg_class is not declared yet. */
reg_class is not declared yet. */
...
@@ -2870,9 +2881,11 @@ while (0)
...
@@ -2870,9 +2881,11 @@ while (0)
: (FROM) == FP_REGS && (TO) == FP_REGS ? 2 \
: (FROM) == FP_REGS && (TO) == FP_REGS ? 2 \
: (FROM) == GR_REGS && (TO) == FP_REGS ? 4 \
: (FROM) == GR_REGS && (TO) == FP_REGS ? 4 \
: (FROM) == FP_REGS && (TO) == GR_REGS ? 4 \
: (FROM) == FP_REGS && (TO) == GR_REGS ? 4 \
: (((FROM) == HI_REG || (FROM) == LO_REG || (FROM) == MD_REGS) \
: (((FROM) == HI_REG || (FROM) == LO_REG \
|| (FROM) == MD_REGS || (FROM) == HILO_REG) \
&& (TO) == GR_REGS) ? 6 \
&& (TO) == GR_REGS) ? 6 \
: (((TO) == HI_REG || (TO) == LO_REG || (TO) == MD_REGS) \
: (((TO) == HI_REG || (TO) == LO_REG \
|| (TO) == MD_REGS || (FROM) == HILO_REG) \
&& (FROM) == GR_REGS) ? 6 \
&& (FROM) == GR_REGS) ? 6 \
: 12)
: 12)
...
@@ -3085,6 +3098,7 @@ while (0)
...
@@ -3085,6 +3098,7 @@ while (0)
&mips_reg_names[64][0], \
&mips_reg_names[64][0], \
&mips_reg_names[65][0], \
&mips_reg_names[65][0], \
&mips_reg_names[66][0], \
&mips_reg_names[66][0], \
&mips_reg_names[67][0], \
}
}
/* print-rtl.c can't use REGISTER_NAMES, since it depends on mips.c.
/* print-rtl.c can't use REGISTER_NAMES, since it depends on mips.c.
...
@@ -3099,7 +3113,7 @@ while (0)
...
@@ -3099,7 +3113,7 @@ while (0)
"$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", \
"$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", \
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", \
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", \
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", \
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", \
"hi", "lo", "
$fcr31"
\
"hi", "lo", "
accum","$fcr31"
\
}
}
/* If defined, a C initializer for an array of structures
/* If defined, a C initializer for an array of structures
...
...
gcc/config/mips/mips.md
View file @
225b8835
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment