diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 5a2897301f9f..765c6f646743 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1099,6 +1099,30 @@ check_implicit_for_i (const riscv_parse_subset_t *rps ATTRIBUTE_UNUSED,
 	      && subset->minor_version < 1));
 }
 
+/* Add the IMPLICIT only when the 'C' extension is also available.  */
+
+static bool
+check_implicit_for_d_c (const riscv_parse_subset_t *rps,
+			const riscv_implicit_subset_t *implicit
+			    ATTRIBUTE_UNUSED,
+			const riscv_subset_t *subset ATTRIBUTE_UNUSED)
+{
+  riscv_subset_t *tmp = NULL;
+  return riscv_lookup_subset (rps->subset_list, "c", &tmp);
+}
+
+/* Add the IMPLICIT only when the 'C' extension is also available
+   and XLEN is 32.  */
+
+static bool
+check_implicit_for_f_c (const riscv_parse_subset_t *rps,
+			const riscv_implicit_subset_t *implicit
+			    ATTRIBUTE_UNUSED,
+			const riscv_subset_t *subset ATTRIBUTE_UNUSED)
+{
+  return *rps->xlen == 32 && check_implicit_for_d_c (rps, implicit, subset);
+}
+
 /* All extension implications.  */
 
 static riscv_implicit_subset_t riscv_implicit_subsets[] =
@@ -1182,6 +1206,7 @@ static riscv_implicit_subset_t riscv_implicit_subsets[] =
   {"zvksg", "zvkg",	check_implicit_always},
   {"zvksc", "zvks",	check_implicit_always},
   {"zvksc", "zvbc",	check_implicit_always},
+  {"c", "zca",		check_implicit_always},
   {"zcf", "zca",	check_implicit_always},
   {"zcd", "zca",	check_implicit_always},
   {"zcb", "zca",	check_implicit_always},
@@ -1192,6 +1217,10 @@ static riscv_implicit_subset_t riscv_implicit_subsets[] =
   {"sscofpmf", "zicsr",		check_implicit_always},
   {"ssstateen", "zicsr",	check_implicit_always},
   {"sstc", "zicsr",		check_implicit_always},
+  /* Complex implications (that should be checked after others).  */
+  {"d", "zcd",		check_implicit_for_d_c},
+  {"f", "zcf",		check_implicit_for_f_c},
+  /* Tail of the list.  */
   {NULL, NULL, NULL}
 };
 
diff --git a/gas/testsuite/gas/riscv/attribute-10.d b/gas/testsuite/gas/riscv/attribute-10.d
index f46692275f19..d93b42a98fa4 100644
--- a/gas/testsuite/gas/riscv/attribute-10.d
+++ b/gas/testsuite/gas/riscv/attribute-10.d
@@ -3,4 +3,4 @@
 #source: empty.s
 Attribute Section: riscv
 File Attributes
-  Tag_RISCV_arch: "rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0"
+  Tag_RISCV_arch: "rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zca1p0_zcd1p0_zcf1p0"
diff --git a/gas/testsuite/gas/riscv/dis-addr-overflow-32.d b/gas/testsuite/gas/riscv/dis-addr-overflow-32.d
index 287c5ea022f3..e966a2069dfd 100644
--- a/gas/testsuite/gas/riscv/dis-addr-overflow-32.d
+++ b/gas/testsuite/gas/riscv/dis-addr-overflow-32.d
@@ -1,4 +1,4 @@
-#as: -march=rv32ic
+#as: -march=rv32i_zca
 #source: dis-addr-overflow.s
 #objdump: -d
 
diff --git a/gas/testsuite/gas/riscv/dis-addr-overflow-64.d b/gas/testsuite/gas/riscv/dis-addr-overflow-64.d
index 1966a5ed7437..6ef02fe1fd97 100644
--- a/gas/testsuite/gas/riscv/dis-addr-overflow-64.d
+++ b/gas/testsuite/gas/riscv/dis-addr-overflow-64.d
@@ -1,4 +1,4 @@
-#as: -march=rv64ic -defsym rv64=1
+#as: -march=rv64i_zca -defsym rv64=1
 #source: dis-addr-overflow.s
 #objdump: -d
 
diff --git a/gas/testsuite/gas/riscv/dis-addr-overflow.s b/gas/testsuite/gas/riscv/dis-addr-overflow.s
index 77ca39c07b66..2ce3a904c1a1 100644
--- a/gas/testsuite/gas/riscv/dis-addr-overflow.s
+++ b/gas/testsuite/gas/riscv/dis-addr-overflow.s
@@ -24,7 +24,7 @@ topbase = 0
 
 target:
 	.option	push
-	.option	arch, -c
+	.option	arch, -zca
 	## Use hi_addr
 	# Load
 	lui	t0, 0xfffff
@@ -50,7 +50,7 @@ target:
 	c.addi	t6, -20
 .ifdef rv64
 	.option	push
-	.option	arch, -c
+	.option	arch, -zca
 	# ADDIW (not compressed)
 	lui	s6, 0xffff8
 	addiw	s7, s6, -24
diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
index 40df34097369..3008157dc049 100644
--- a/gas/testsuite/gas/riscv/mapping-symbols.d
+++ b/gas/testsuite/gas/riscv/mapping-symbols.d
@@ -9,44 +9,44 @@ SYMBOL TABLE:
 0+00 l    d  .data	0+00 .data
 0+00 l    d  .bss	0+00 .bss
 0+00 l    d  .text.cross.section.A	0+00 .text.cross.section.A
-0+00 l       .text.cross.section.A	0+00 \$xrv32i2p1_c2p0
+0+00 l       .text.cross.section.A	0+00 \$xrv32i2p1_zca1p0
 0+00 l    d  .text.corss.section.B	0+00 .text.corss.section.B
-0+00 l       .text.corss.section.B	0+00 \$xrv32i2p1_c2p0
+0+00 l       .text.corss.section.B	0+00 \$xrv32i2p1_zca1p0
 0+02 l       .text.corss.section.B	0+00 \$xrv32i2p1
 0+00 l    d  .text.data	0+00 .text.data
 0+00 l       .text.data	0+00 \$d
-0+08 l       .text.data	0+00 \$xrv32i2p1_c2p0
+0+08 l       .text.data	0+00 \$xrv32i2p1_zca1p0
 0+0c l       .text.data	0+00 \$d
 0+00 l    d  .text.odd.align.start.insn	0+00 .text.odd.align.start.insn
-0+00 l       .text.odd.align.start.insn	0+00 \$xrv32i2p1_c2p0
+0+00 l       .text.odd.align.start.insn	0+00 \$xrv32i2p1_zca1p0
 0+02 l       .text.odd.align.start.insn	0+00 \$d
 0+08 l       .text.odd.align.start.insn	0+00 \$xrv32i2p1
 0+00 l    d  .text.odd.align.start.data	0+00 .text.odd.align.start.data
 0+00 l       .text.odd.align.start.data	0+00 \$d
 0+00 l    d  .text.zero.fill.first	0+00 .text.zero.fill.first
-0+00 l       .text.zero.fill.first	0+00 \$xrv32i2p1_c2p0
+0+00 l       .text.zero.fill.first	0+00 \$xrv32i2p1_zca1p0
 0+00 l    d  .text.zero.fill.last	0+00 .text.zero.fill.last
-0+00 l       .text.zero.fill.last	0+00 \$xrv32i2p1_c2p0
+0+00 l       .text.zero.fill.last	0+00 \$xrv32i2p1_zca1p0
 0+02 l       .text.zero.fill.last	0+00 \$x
 0+00 l    d  .text.zero.fill.align.A	0+00 .text.zero.fill.align.A
-0+00 l       .text.zero.fill.align.A	0+00 \$xrv32i2p1_c2p0
+0+00 l       .text.zero.fill.align.A	0+00 \$xrv32i2p1_zca1p0
 0+00 l    d  .text.zero.fill.align.B	0+00 .text.zero.fill.align.B
 0+00 l       .text.zero.fill.align.B	0+00 \$xrv32i2p1
 0+00 l    d  .text.last.section	0+00 .text.last.section
 0+00 l       .text.last.section	0+00 \$xrv32i2p1
 0+04 l       .text.last.section	0+00 \$d
 0+00 l    d  .text.section.padding	0+00 .text.section.padding
-0+00 l       .text.section.padding	0+00 \$xrv32i2p1_c2p0
-0+04 l       .text.section.padding	0+00 \$xrv32i2p1_a2p1_c2p0
+0+00 l       .text.section.padding	0+00 \$xrv32i2p1_zca1p0
+0+04 l       .text.section.padding	0+00 \$xrv32i2p1_a2p1_zca1p0
 0+06 l       .text.section.padding	0+00 \$d
 0+00 l    d  .text.relax.align	0+00 .text.relax.align
-0+00 l       .text.relax.align	0+00 \$xrv32i2p1_c2p0
+0+00 l       .text.relax.align	0+00 \$xrv32i2p1_zca1p0
 0+08 l       .text.relax.align	0+00 \$xrv32i2p1
 0+0a l       .text.section.padding	0+00 \$x
 0+03 l       .text.odd.align.start.insn	0+00 \$d
 0+04 l       .text.odd.align.start.insn	0+00 \$x
 0+01 l       .text.odd.align.start.data	0+00 \$d
-0+02 l       .text.odd.align.start.data	0+00 \$xrv32i2p1_c2p0
+0+02 l       .text.odd.align.start.data	0+00 \$xrv32i2p1_zca1p0
 0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
 0+00 g       .text.cross.section.A	0+00 funcA
 0+00 g       .text.corss.section.B	0+00 funcB
diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s
index 3014a69e7920..2fbb62977c3a 100644
--- a/gas/testsuite/gas/riscv/mapping.s
+++ b/gas/testsuite/gas/riscv/mapping.s
@@ -1,4 +1,4 @@
-.attribute arch, "rv32ic"
+.attribute arch, "rv32i_zca"
 .option norelax			# FIXME: assembler fill the paddings after parsing everything,
 				# so we probably won't fill anything for the norelax region when
 				# the riscv_opts.relax is enabled at somewhere.
@@ -8,13 +8,13 @@
 .global funcA
 funcA:
 addi	a0, zero, 1		# rv32i
-.option arch, +c
-j	funcA			# rv32ic
+.option arch, +zca
+j	funcA			# rv32i_zca
 .section .text.corss.section.B, "ax"
 .globl funcB
 funcB:
-addi	a0, zero, 2		# rv32ic, need to be added since start of section
-.option arch, -c
+addi	a0, zero, 2		# rv32i_zca, need to be added since start of section
+.option arch, -zca
 j	funcB			# rv32i
 .option pop
 
@@ -22,7 +22,7 @@ j	funcB			# rv32i
 .option push
 .word	0			# $d
 .long	1
-addi	a0, zero, 1		# rv32ic
+addi	a0, zero, 1		# rv32i_zca
 .data
 .word	2			# don't add mapping symbols for non-text section
 .section .text.data
@@ -35,10 +35,10 @@ addi	a0, zero, 2		# $x, but same as previous addi, so removed
 .section .text.odd.align.start.insn, "ax"
 .option push
 .option norelax
-.option arch, +c
-addi	a0, zero, 1		# $xrv32ic
+.option arch, +zca
+addi	a0, zero, 1		# $xrv32i_zca
 .byte	1			# $d
-.option arch, -c
+.option arch, -zca
 .align	3			# odd alignment, $x replaced by $d + $x
 addi	a0, zero, 2		# $xrv32i
 .option pop
@@ -46,9 +46,9 @@ addi	a0, zero, 2		# $xrv32i
 .section .text.odd.align.start.data, "ax"
 .option push
 .option norelax
-.option arch, +c
+.option arch, +zca
 .byte	1			# $d
-.align	2			# odd alignment, $xrv32ic replaced by $d + $xrv32ic
+.align	2			# odd alignment, $xrv32i_zca replaced by $d + $xrv32i_zca
 addi	a0, zero, 1
 .option pop
 
@@ -56,13 +56,13 @@ addi	a0, zero, 1
 .option push
 .option norelax
 .fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol
-addi	a0, zero, 1		# $xrv32ic
+addi	a0, zero, 1		# $xrv32i_zca
 .option pop
 
 .section .text.zero.fill.last, "ax"
 .option push
 .option norelax
-addi	a0, zero, 1		# $xrv32ic
+addi	a0, zero, 1		# $xrv32i_zca
 .fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol
 addi	a0, zero, 2		# $x, FIXME: need find a way to remove?
 .option pop
@@ -71,8 +71,8 @@ addi	a0, zero, 2		# $x, FIXME: need find a way to remove?
 .section .text.zero.fill.align.A, "ax"
 .option push
 .option norelax
-.align	2			# $xrv32ic, .align and .fill are in the different frag, so neither be removed
-.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
+.align	2			# $xrv32i_zca, .align and .fill are in the different frag, so neither be removed
+.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32i_zca
 addi	a0, zero, 1		# $x, should be removed in riscv_check_mapping_symbols
 addi	a0, zero, 2
 .option pop
@@ -81,10 +81,10 @@ addi	a0, zero, 2
 .section .text.zero.fill.align.B, "ax"
 .option push
 .option norelax
-.align	2			# $xrv32ic, .align and .fill are in the different frag, so neither be removed,
+.align	2			# $xrv32i_zca, .align and .fill are in the different frag, so neither be removed,
 				# but will be removed in riscv_check_mapping_symbols
-.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
-.option arch, -c
+.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32i_zca
+.option arch, -zca
 addi	a0, zero, 1		# $xrv32i
 addi	a0, zero, 2
 .option pop
@@ -92,7 +92,7 @@ addi	a0, zero, 2
 .section .text.last.section, "ax"
 .option push
 .option norelax
-.option arch, -c
+.option arch, -zca
 addi	a0, zero, 1		# $xrv32i
 .word	1			# $d
 .align	2			# zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
@@ -102,20 +102,20 @@ addi	a0, zero, 1		# $xrv32i
 .option push
 .option norelax
 .align	2
-addi	a0, zero, 1		# $rv32ic
+addi	a0, zero, 1		# $rv32i_zca
 .option arch, +a
 .align	2			# 2-byte padding, $x, removed
-addi	a0, zero, 2		# $xrv32iac
+addi	a0, zero, 2		# $xrv32ia_zca
 .word	1			# $d
 .option pop			# 2-byte padding, $x
 
 .section .text.relax.align, "ax"
 .option push
 .option relax
-.option arch, rv32ic
-.balign	4			# $xrv32ic, add at the start of section
+.option arch, rv32i_zca
+.balign	4			# $xrv32i_zca, add at the start of section
 addi	a0, zero, 1		# $x, won't added
-.option arch, -c
+.option arch, -zca
 .align	3			# $x, won't added
 addi	a0, zero, 2		# $xrv32i
 .option pop
diff --git a/gas/testsuite/gas/riscv/march-imply-c-d-32.d b/gas/testsuite/gas/riscv/march-imply-c-d-32.d
new file mode 100644
index 000000000000..8d9877b63968
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-imply-c-d-32.d
@@ -0,0 +1,6 @@
+#as: -march=rv32idc -march-attr -misa-spec=20191213
+#readelf: -A
+#source: empty.s
+Attribute Section: riscv
+File Attributes
+  Tag_RISCV_arch: "rv32i2p1_f2p2_d2p2_c2p0_zicsr2p0_zca1p0_zcd1p0_zcf1p0"
diff --git a/gas/testsuite/gas/riscv/march-imply-c-d-64.d b/gas/testsuite/gas/riscv/march-imply-c-d-64.d
new file mode 100644
index 000000000000..31f8fad00dac
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-imply-c-d-64.d
@@ -0,0 +1,6 @@
+#as: -march=rv64idc -march-attr -misa-spec=20191213
+#readelf: -A
+#source: empty.s
+Attribute Section: riscv
+File Attributes
+  Tag_RISCV_arch: "rv64i2p1_f2p2_d2p2_c2p0_zicsr2p0_zca1p0_zcd1p0"
diff --git a/gas/testsuite/gas/riscv/march-imply-c.d b/gas/testsuite/gas/riscv/march-imply-c.d
new file mode 100644
index 000000000000..830dd9f2acc4
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-imply-c.d
@@ -0,0 +1,6 @@
+#as: -march=rv32ic -march-attr -misa-spec=20191213
+#readelf: -A
+#source: empty.s
+Attribute Section: riscv
+File Attributes
+  Tag_RISCV_arch: "rv32i2p1_c2p0_zca1p0"
diff --git a/gas/testsuite/gas/riscv/march-ok-reorder.d b/gas/testsuite/gas/riscv/march-ok-reorder.d
index 030f8b150189..db92029e7594 100644
--- a/gas/testsuite/gas/riscv/march-ok-reorder.d
+++ b/gas/testsuite/gas/riscv/march-ok-reorder.d
@@ -4,4 +4,4 @@
 
 Attribute Section: riscv
 File Attributes
-  Tag_RISCV_arch: "rv32i2p0_m1p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_xbar2p0_xfoo2p0"
+  Tag_RISCV_arch: "rv32i2p0_m1p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zca1p0_zcd1p0_zcf1p0_zba1p0_xbar2p0_xfoo2p0"
diff --git a/gas/testsuite/gas/riscv/option-arch-01.s b/gas/testsuite/gas/riscv/option-arch-01.s
index 50285fc8c735..1bde865d1ff2 100644
--- a/gas/testsuite/gas/riscv/option-arch-01.s
+++ b/gas/testsuite/gas/riscv/option-arch-01.s
@@ -1,7 +1,7 @@
-.attribute arch, "rv64ic"
+.attribute arch, "rv64i_zca"
 add	a0, a0, a1
 .option push
-.option arch, +d2p0, -c, +xvendor1p0
+.option arch, +d2p0, -zca, +xvendor1p0
 add	a0, a0, a1
 frcsr	a0	# Should add mapping symbol with ISA here, and then dump it to frcsr.
 .option push
diff --git a/gas/testsuite/gas/riscv/option-arch-01b.d b/gas/testsuite/gas/riscv/option-arch-01b.d
index 8f4284d5f15b..5d7176975061 100644
--- a/gas/testsuite/gas/riscv/option-arch-01b.d
+++ b/gas/testsuite/gas/riscv/option-arch-01b.d
@@ -4,5 +4,5 @@
 
 Attribute Section: riscv
 File Attributes
-  Tag_RISCV_arch: "rv64i2p0_c2p0"
+  Tag_RISCV_arch: "rv64i2p0_zca1p0"
 #...
diff --git a/gas/testsuite/gas/riscv/option-arch-02.d b/gas/testsuite/gas/riscv/option-arch-02.d
index 3c27419f9d36..8d75b468b257 100644
--- a/gas/testsuite/gas/riscv/option-arch-02.d
+++ b/gas/testsuite/gas/riscv/option-arch-02.d
@@ -4,5 +4,5 @@
 
 Attribute Section: riscv
 File Attributes
-  Tag_RISCV_arch: "rv64i2p0_m3p0_f2p0_d3p0_c2p0_zmmul1p0_xvendor32x3p0"
+  Tag_RISCV_arch: "rv64i2p0_m3p0_f2p0_d3p0_zmmul1p0_zca1p0_xvendor32x3p0"
 #...
diff --git a/gas/testsuite/gas/riscv/option-arch-02.s b/gas/testsuite/gas/riscv/option-arch-02.s
index e0f5de321d67..109875985f4d 100644
--- a/gas/testsuite/gas/riscv/option-arch-02.s
+++ b/gas/testsuite/gas/riscv/option-arch-02.s
@@ -1,7 +1,7 @@
-.attribute arch, "rv64ic"
+.attribute arch, "rv64i_zca"
 add	a0, a0, a1
 .option push
-.option arch, +d2p0, -c, +xvendor1p0
+.option arch, +d2p0, -zca, +xvendor1p0
 add	a0, a0, a1
 frcsr	a0
 .option pop
diff --git a/gas/testsuite/gas/riscv/option-arch-03.d b/gas/testsuite/gas/riscv/option-arch-03.d
index 62d7f7d5ed21..06b9c6b375e4 100644
--- a/gas/testsuite/gas/riscv/option-arch-03.d
+++ b/gas/testsuite/gas/riscv/option-arch-03.d
@@ -4,5 +4,5 @@
 
 Attribute Section: riscv
 File Attributes
-  Tag_RISCV_arch: "rv32i2p1_c2p0"
+  Tag_RISCV_arch: "rv32i2p1_c2p0_zca1p0"
 #...
diff --git a/gas/testsuite/gas/riscv/option-arch-03.s b/gas/testsuite/gas/riscv/option-arch-03.s
index ccdb1c354b0f..60da2605fe3e 100644
--- a/gas/testsuite/gas/riscv/option-arch-03.s
+++ b/gas/testsuite/gas/riscv/option-arch-03.s
@@ -1,3 +1,3 @@
-.attribute arch, "rv64ic"
-.option arch, +d2p0, -c
+.attribute arch, "rv64i_zca"
+.option arch, +d2p0, -zca
 .option arch, rv32i2p1c2p0
