arch-x86: Work around a bug in g++ 6 and 7.

These versions of g++ don't handle parameter pack expansion correctly
when there is a parameter pack defined at the class level and then one
which is defined by the constructor itself. Even though it knows what
the outter parameter pack contains, it still re-assigns it to be empty
and puts all arguments into the later parameter pack.

To work around this problem, we will explicitly put the class level
parameters into a tuple, which we then have to go through extra
acrobatics to explode and pass into base class constructors.

That also means that in all subclasses, the arguments which go into the
tuple need to be wrapped in {}s to group them into constructor arguments
for the tuple.

Change-Id: I3139eebd7042b02f50862d88be5c940583a2a809
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/45820
Maintainer: Gabe Black <gabe.black@gmail.com>
Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu>
Reviewed-by: Matt Sinclair <mattdsinclair@gmail.com>
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2021-05-20 22:49:22 -07:00
parent 8949521ae3
commit 1a33023815
9 changed files with 33 additions and 16 deletions

View File

@@ -39,6 +39,8 @@
#ifndef __ARCH_X86_INSTS_MICROLDSTOP_HH__
#define __ARCH_X86_INSTS_MICROLDSTOP_HH__
#include <tuple>
#include "arch/x86/insts/microop.hh"
#include "arch/x86/insts/microop_args.hh"
#include "arch/x86/ldstflags.hh"
@@ -89,7 +91,7 @@ class LdStOp : public InstOperands<MemOp, FoldedDataOp, AddrOp>
Request::FlagsType mem_flags, OpClass op_class) :
InstOperands<MemOp, FoldedDataOp, AddrOp>(
mach_inst, mnem, inst_mnem, set_flags, op_class,
_data, { _scale, _index, _base, _disp, _segment },
{ _data, { _scale, _index, _base, _disp, _segment } },
data_size, address_size, mem_flags | _segment.index)
{}
};
@@ -108,7 +110,7 @@ class LdStFpOp : public InstOperands<MemOp, FloatDataOp, AddrOp>
Request::FlagsType mem_flags, OpClass op_class) :
InstOperands<MemOp, FloatDataOp, AddrOp>(
mach_inst, mnem, inst_mnem, set_flags, op_class,
_data, { _scale, _index, _base, _disp, _segment },
{ _data, { _scale, _index, _base, _disp, _segment } },
data_size, address_size, mem_flags | _segment.index)
{}
};
@@ -126,7 +128,7 @@ class MemNoDataOp : public InstOperands<MemOp, AddrOp>
Request::FlagsType mem_flags, OpClass op_class) :
InstOperands<MemOp, AddrOp>(
mach_inst, mnem, inst_mnem, set_flags, op_class,
{ _scale, _index, _base, _disp, _segment },
{ { _scale, _index, _base, _disp, _segment } },
data_size, address_size, mem_flags | _segment.index)
{}
};
@@ -148,7 +150,7 @@ class LdStSplitOp :
Request::FlagsType mem_flags, OpClass op_class) :
InstOperands<MemOp, FoldedDataLowOp, FoldedDataHiOp, AddrOp>(
mach_inst, mnem, inst_mnem, set_flags, op_class,
data_low, data_hi, { _scale, _index, _base, _disp, _segment },
{ data_low, data_hi, { _scale, _index, _base, _disp, _segment } },
data_size, address_size, mem_flags | _segment.index)
{}
};

View File

@@ -31,6 +31,8 @@
#include <cstdint>
#include <sstream>
#include <string>
#include <tuple>
#include <utility>
#include "arch/x86/insts/static_inst.hh"
#include "arch/x86/regs/int.hh"
@@ -338,13 +340,26 @@ struct AddrOp
template <typename Base, typename ...Operands>
class InstOperands : public Base, public Operands...
{
private:
using ArgTuple = std::tuple<typename Operands::ArgType...>;
template <std::size_t ...I, typename ...CTorArgs>
InstOperands(std::index_sequence<I...>, ExtMachInst mach_inst,
const char *mnem, const char *inst_mnem, uint64_t set_flags,
OpClass op_class, GEM5_VAR_USED ArgTuple args,
CTorArgs... ctor_args) :
Base(mach_inst, mnem, inst_mnem, set_flags, op_class, ctor_args...),
Operands(this, std::get<I>(args))...
{}
protected:
template <typename ...CTorArgs>
InstOperands(ExtMachInst mach_inst, const char *mnem,
const char *inst_mnem, uint64_t set_flags, OpClass op_class,
typename Operands::ArgType... args, CTorArgs... ctor_args) :
Base(mach_inst, mnem, inst_mnem, set_flags, op_class, ctor_args...),
Operands(this, args)...
ArgTuple args, CTorArgs... ctor_args) :
InstOperands(std::make_index_sequence<sizeof...(Operands)>{},
mach_inst, mnem, inst_mnem, set_flags, op_class,
std::move(args), ctor_args...)
{}
std::string

View File

@@ -42,7 +42,7 @@ class MicroHalt : public InstOperands<X86MicroopBase>
InstOperands<X86MicroopBase>(mach_inst, "halt", inst_mnem,
set_flags | (1ULL << StaticInst::IsNonSpeculative) |
(1ULL << StaticInst::IsQuiesce),
No_OpClass)
No_OpClass, {})
{}
Fault

View File

@@ -92,7 +92,7 @@ def template MicroFpOpConstructor {{
const char *inst_mnem, uint64_t set_flags,
uint8_t data_size, int8_t _spm, Args... args) :
%(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
%(op_class)s, args..., data_size, _spm)
%(op_class)s, { args... }, data_size, _spm)
{
%(set_reg_idx_arr)s;
%(constructor)s;

View File

@@ -64,7 +64,7 @@ def template MicroLimmOpDeclare {{
uint64_t set_flags, Dest _dest,
uint64_t _imm, uint8_t data_size) :
%(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
%(op_class)s, _dest, _imm, data_size, 0)
%(op_class)s, { _dest, _imm }, data_size, 0)
{
%(set_reg_idx_arr)s;
%(constructor)s;

View File

@@ -58,7 +58,7 @@ def template MediaOpDeclare {{
uint64_t set_flags, uint8_t src_size, uint8_t dest_size,
uint16_t _ext, Args... args) :
%(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
%(op_class)s, args..., src_size, dest_size, _ext)
%(op_class)s, { args... }, src_size, dest_size, _ext)
{
%(set_reg_idx_arr)s;
%(constructor)s;

View File

@@ -79,7 +79,7 @@ def template MicroRegOpDeclare {{
uint64_t set_flags, uint8_t data_size, uint16_t _ext,
Args... args) :
%(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
%(op_class)s, args..., data_size, _ext)
%(op_class)s, { args... }, data_size, _ext)
{
%(set_reg_idx_arr)s;
%(constructor)s;
@@ -102,7 +102,7 @@ def template MicroRegOpBranchDeclare {{
uint64_t set_flags, uint8_t data_size, uint16_t _ext,
Args... args) :
%(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
%(op_class)s, args..., data_size, _ext)
%(op_class)s, { args... }, data_size, _ext)
{
%(set_reg_idx_arr)s;
%(constructor)s;

View File

@@ -43,7 +43,7 @@ def template BrDeclare {{
%(class_name)s(ExtMachInst mach_inst, const char *inst_mnem,
uint64_t set_flags, uint16_t _target, uint8_t _cc) :
%(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
%(op_class)s, _target, _cc)
%(op_class)s, { _target }, _cc)
{
%(set_reg_idx_arr)s;
%(constructor)s;
@@ -77,7 +77,7 @@ def template EretDeclare {{
%(class_name)s(ExtMachInst mach_inst, const char *inst_mnem,
uint64_t set_flags, uint8_t _cc) :
%(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
%(op_class)s, _cc)
%(op_class)s, {}, _cc)
{
%(set_reg_idx_arr)s;
%(constructor)s;

View File

@@ -75,7 +75,7 @@ def template MicroFaultConstructor {{
ExtMachInst mach_inst, const char *inst_mnem, uint64_t set_flags,
Fault _fault, uint8_t _cc) :
%(base_class)s(mach_inst, "fault", inst_mnem, set_flags, No_OpClass,
_fault, _cc)
{ _fault }, _cc)
{
%(set_reg_idx_arr)s;
%(constructor)s;