diff --git a/gdb/testsuite/gdb.cp/call-method-register.cc b/gdb/testsuite/gdb.cp/call-method-register.cc
index d60fee03701..91cbf13ebca 100644
--- a/gdb/testsuite/gdb.cp/call-method-register.cc
+++ b/gdb/testsuite/gdb.cp/call-method-register.cc
@@ -1,6 +1,6 @@
 /* This testcase is part of GDB, the GNU debugger.
 
-   Copyright 1993-2022 Free Software Foundation, Inc.
+   Copyright 2022 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -15,54 +15,9 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#if defined __x86_64__
-# define ASM_REG "rax"
-#elif defined __i386__
-# define ASM_REG "eax"
-#elif defined __powerpc64__
-# define ASM_REG "r9"
-#else
-# error "port me"
-#endif
-
-/* A class small enough that it fits in a register.  */
-struct small
-{
-  int x;
-  int method ();
-};
-
-int
-small::method ()
-{
-  return x + 5;
-}
-
-int
-register_class ()
-{
-  /* Given the use of the GNU register-asm local variables extension,
-     the compiler puts this variable in a register.  This means that
-     GDB can't call any methods for this variable, which is what we
-     want to test.  */
-  register small v asm (ASM_REG);
-
-  int i;
-
-  /* Perform a computation sufficiently complicated that optimizing
-     compilers won't optimize out the variable.  If some compiler
-     constant-folds this whole loop, maybe using a parameter to this
-     function here would help.  */
-  v.x = 0;
-  for (i = 0; i < 13; ++i)
-    v.x += i;
-  --v.x; /* v.x is now 77 */
-  return v.x + 5; /* set breakpoint here */
-}
-
 int
 main ()
 {
-  register_class ();
+  asm ("main_label: .globl main_label");
   return 0;
 }
diff --git a/gdb/testsuite/gdb.cp/call-method-register.exp b/gdb/testsuite/gdb.cp/call-method-register.exp
index a98b11e4c11..a86ea1e44f9 100644
--- a/gdb/testsuite/gdb.cp/call-method-register.exp
+++ b/gdb/testsuite/gdb.cp/call-method-register.exp
@@ -19,43 +19,93 @@
 if { [skip_cplus_tests] } { continue }
 
 load_lib "cp-support.exp"
+load_lib dwarf.exp
 
-standard_testfile .cc
+standard_testfile .cc -dw.S
 
-if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile \
+	 {debug c++}]} {
     return -1
 }
 
-if {![test_compiler_info gcc-*-* c++]} {
-    untested "test relies on a gcc extension"
-    return
-}
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+
+    set main_result \
+	[function_range main ${::srcdir}/${::subdir}/${::srcfile}]
+    set main_start [lindex $main_result 0]
+    set main_length [lindex $main_result 1]
+
+    cu {} {
+	compile_unit {
+	    {DW_AT_language @DW_LANG_C_plus_plus}
+	    {DW_AT_name	    $::srcfile}
+	    {DW_AT_comp_dir /tmp}
+	} {
+	    declare_labels int_type_label struct_type_label \
+		struct_ptr_type_label
+	    set ptr_size [get_sizeof "void *" 96]
+
+	    DW_TAG_subprogram {
+		{name main}
+		{low_pc $main_start addr}
+		{high_pc $main_length data8}
+		{DW_AT_type :$int_type_label}
+	    }
+
+	    int_type_label: DW_TAG_base_type {
+		{DW_AT_byte_size 4 DW_FORM_sdata}
+		{DW_AT_encoding @DW_ATE_signed}
+		{DW_AT_name int}
+	    }
+
+	    struct_type_label: DW_TAG_structure_type {
+		{DW_AT_byte_size 4 DW_FORM_sdata}
+		{DW_AT_name small}
+	    } {
+		member {
+		    {name xxx}
+		    {type :$int_type_label}
+		    {data_member_location 0 data1}
+		}
+		subprogram {
+		    {name yyy}
+		    {type :$int_type_label}
+		    {data_member_location 0 data1}
+		} {
+		    formal_parameter {
+			{type :$struct_ptr_type_label}
+			{artificial 1 flag_present}
+		    }
+		}
+	    }
 
-proc test_call_register_class {} {
-    global gdb_prompt
+	    struct_ptr_type_label: DW_TAG_pointer_type {
+		{DW_AT_byte_size $ptr_size DW_FORM_data1}
+		{type :$struct_type_label}
+	    }
 
-    if ![runto_main] {
-	return
+	    DW_TAG_variable {
+		{DW_AT_name global_var}
+		{DW_AT_type :$struct_type_label}
+		{DW_AT_location {
+		    DW_OP_reg0
+		} SPECIAL_expr}
+		{external 1 flag}
+	    }
+	}
     }
+}
 
-    set bp_location [gdb_get_line_number "set breakpoint here"]
-    gdb_breakpoint $bp_location
-    gdb_continue_to_breakpoint "break here"
-
-    # This class is so small that an instance of it can fit in a register.
-    # When gdb tries to call a method, it gets embarrassed about taking
-    # the address of a register.
-    #
-    # That message is a PASS, not an XFAIL, because gdb prints an
-    # informative message and declines to do something impossible.
-    #
-    # The method call actually succeeds if the compiler allocates very
-    # small classes in memory instead of registers.  If that happens,
-    # it's a FAIL, because the testcase is written in a form such that
-    # it should not happen.
-    gdb_test "print v.method ()" \
-	"Address requested for identifier \"v\" which is in register .*" \
-	"call method on register local"
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+	  [list $srcfile $asm_file] {nodebug}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
 }
 
-test_call_register_class
+gdb_test "print global_var.yyy ()" \
+    "Address requested for identifier \"global_var\" which is in register .*" \
+    "call method on register local"
